From 30bc9d8f57585b70c0fbf16e3e1ee1d091db2576 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 14 Dec 2023 17:53:39 +0100 Subject: [PATCH 001/265] PSPAYPAL-680-Vaulting: integrate vaulting feature --- metadata.php | 68 +++++++++++- migration/data/Version20231129135614.php | 48 +++++++++ .../Admin/PayPalConfigController.php | 3 + .../PayPalVaultingCardController.php | 22 ++++ src/Controller/PayPalVaultingController.php | 22 ++++ src/Controller/PaymentController.php | 32 +++++- src/Controller/VaultingTokenController.php | 94 ++++++++++++++++ src/Core/Api/VaultingService.php | 11 +- src/Core/OrderRequestFactory.php | 99 +++++++++++++++-- src/Core/PayPalDefinitions.php | 8 ++ src/Core/ServiceFactory.php | 11 ++ src/Core/ViewConfig.php | 9 ++ src/Service/ModuleSettings.php | 5 + src/Service/Payment.php | 3 +- translations/de/oscpaypal_de_lang.php | 72 ++++++++----- translations/en/oscpaypal_en_lang.php | 14 +++ .../blocks/page/account/inc/account_menu.tpl | 9 ++ views/blocks/page/checkout/change_payment.tpl | 61 +++++++++++ views/blocks/page/checkout/thankyou.tpl | 13 +++ .../frontend/blocks/layout/base__base_js.tpl | 7 +- .../page/account/account_vaulting_card.tpl | 102 ++++++++++++++++++ .../page/account/account_vaulting_paypal.tpl | 65 +++++++++++ .../frontend/blocks/vaultedpaymentsources.tpl | 23 ++++ 23 files changed, 756 insertions(+), 45 deletions(-) create mode 100644 migration/data/Version20231129135614.php create mode 100644 src/Controller/PayPalVaultingCardController.php create mode 100644 src/Controller/PayPalVaultingController.php create mode 100644 src/Controller/VaultingTokenController.php create mode 100644 views/blocks/page/account/inc/account_menu.tpl create mode 100644 views/blocks/page/checkout/change_payment.tpl create mode 100644 views/blocks/page/checkout/thankyou.tpl create mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl create mode 100644 views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl create mode 100644 views/smarty/frontend/blocks/vaultedpaymentsources.tpl diff --git a/metadata.php b/metadata.php index dd046d2f..70b655dc 100644 --- a/metadata.php +++ b/metadata.php @@ -29,8 +29,11 @@ use OxidSolutionCatalysts\PayPal\Controller\Admin\OrderOverview as PayPalOrderOverviewController; use OxidSolutionCatalysts\PayPal\Controller\OrderController as PayPalFrontEndOrderController; use OxidSolutionCatalysts\PayPal\Controller\PaymentController as PayPalPaymentController; +use OxidSolutionCatalysts\PayPal\Controller\PayPalVaultingCardController; use OxidSolutionCatalysts\PayPal\Controller\ProxyController; +use OxidSolutionCatalysts\PayPal\Controller\VaultingTokenController; use OxidSolutionCatalysts\PayPal\Controller\WebhookController; +use OxidSolutionCatalysts\PayPal\Controller\PayPalVaultingController; use OxidSolutionCatalysts\PayPal\Core\InputValidator as PayPalInputValidator; use OxidSolutionCatalysts\PayPal\Core\ShopControl as PayPalShopControl; use OxidSolutionCatalysts\PayPal\Core\ViewConfig as PayPalViewConfig; @@ -81,10 +84,13 @@ State::class => PayPalState::class ], 'controllers' => [ - 'oscpaypalconfig' => PayPalConfigController::class, - 'oscpaypalwebhook' => WebhookController::class, - 'oscpaypalproxy' => ProxyController::class, - 'oscpaypalorder' => PayPalOrderController::class, + 'oscpaypalconfig' => PayPalConfigController::class, + 'oscpaypalwebhook' => WebhookController::class, + 'oscpaypalproxy' => ProxyController::class, + 'oscpaypalorder' => PayPalOrderController::class, + 'oscaccountvault' => PayPalVaultingController::class, + 'oscaccountvaultcard' => PayPalVaultingCardController::class, + 'osctokencontroller' => VaultingTokenController::class, ], 'events' => [ 'onActivate' => '\OxidSolutionCatalysts\PayPal\Core\Events\Events::onActivate', @@ -101,6 +107,43 @@ '@osc_paypal/frontend/paymentbuttons.tpl' => 'views/smarty/frontend/paymentbuttons.tpl', '@osc_paypal/frontend/pui_flow.tpl' => 'views/smarty/frontend/pui_flow.tpl', '@osc_paypal/frontend/select_payment.tpl' => 'views/smarty/frontend/select_payment.tpl', + // Admin: Config + 'oscpaypalconfig.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalconfig.tpl', + + // Admin: Order + 'oscpaypalorder.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder.tpl', + 'oscpaypalorder_ppplus.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder_ppplus.tpl', + 'oscpaypalorder_pp.tpl' => 'osc/paypal/views/admin/tpl/oscpaypalorder_pp.tpl', + + 'modules/osc/paypal/paymentbuttons.tpl' => 'osc/paypal/views/tpl/shared/paymentbuttons.tpl', + + 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', + 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', + 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', + 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', + 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', + 'modules/osc/paypal/checkout_order_btn_submit_bottom_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/checkout_order_btn_submit_bottom.tpl', + 'modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/checkout_order_btn_submit_bottom.tpl', + + // PAYPAL-486 Register templates for overloading here; + // use theme name in key when theme-specific. Shared templates don't receive a theme-specific key. + 'modules/osc/paypal/acdc.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/acdc.tpl', + 'modules/osc/paypal/sepa_cc_alternative.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/sepa_cc_alternative.tpl', + 'modules/osc/paypal/base_js.tpl' => 'osc/paypal/views/tpl/shared/layout/base_js.tpl', + 'modules/osc/paypal/base_style.tpl' => 'osc/paypal/views/tpl/shared/layout/base_style.tpl', + 'modules/osc/paypal/basket_btn_next_bottom.tpl' => + 'osc/paypal/views/tpl/shared/page/checkout/basket_btn_next_bottom.tpl', + 'modules/osc/paypal/select_payment.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/select_payment.tpl', + 'modules/osc/paypal/details_productmain_tobasket.tpl' => + 'osc/paypal/views/tpl/shared/page/details/inc/details_productmain_tobasket.tpl', + 'modules/osc/paypal/dd_layout_page_header_icon_menu_minibasket_functions.tpl' => + 'osc/paypal/views/tpl/shared/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl', + // PAYPAL-486 Theme-specific + 'modules/osc/paypal/change_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/change_payment.tpl', + 'modules/osc/paypal/change_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/change_payment.tpl', + + // PSPAYPAL-491 Installment banners + 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', ], 'blocks' => [ [ @@ -194,6 +237,17 @@ 'block' => 'start_newest_articles', 'file' => 'views/smarty/frontend/blocks/page/shop/start__start_newest_articles.tpl', ], + [ + 'template' => 'page/account/inc/account_menu.tpl', + 'block' => 'account_menu', + 'file' => '/views/blocks/page/account/inc/account_menu.tpl', + ], + [ + 'template' => 'page/checkout/thankyou.tpl', + 'block' => 'checkout_thankyou_info', + 'file' => '/views/blocks/page/checkout/thankyou.tpl', + ], + // <-- PSPAYPAL-491 [ 'template' => 'widget/minibasket/minibasket.tpl', 'block' => 'dd_layout_page_header_icon_menu_minibasket_functions', @@ -469,5 +523,11 @@ 'value' => 3.5, 'group' => null ], + [ + 'name' => 'oscPayPalSetVaulting', + 'type' => 'bool', + 'value' => false, + 'group' => null + ], ], ]; diff --git a/migration/data/Version20231129135614.php b/migration/data/Version20231129135614.php new file mode 100644 index 00000000..96baebae --- /dev/null +++ b/migration/data/Version20231129135614.php @@ -0,0 +1,48 @@ +updateUserTable($schema); + } + + public function down(Schema $schema) : void + { + } + + protected function updateUserTable(Schema $schema) + { + $user = $schema->getTable('oxuser'); + if (!$user->hasColumn('OSCPAYPALVAULTSETUPTOKEN')) { + $user->addColumn( + 'OSCPAYPALVAULTSETUPTOKEN', + 'string', + ['columnDefinition' => 'char(32) collate latin1_general_ci default NULL'] + ); + } + if (!$user->hasColumn('OSCPAYPALCUSTOMERID')) { + $user->addColumn( + 'OSCPAYPALCUSTOMERID', + 'string', + ['columnDefinition' => 'char(32) collate latin1_general_ci default NULL', + 'comment' => 'PayPal Customer ID used for Vaulting '] + ); + } + } +} diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index c6fa0c3b..ed2c19c9 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -280,6 +280,9 @@ protected function handleSpecialFields(array $conf): array $dAmount = (float) str_replace(',', '.', $conf['oscPayPalDefaultShippingPriceExpress']); $conf['oscPayPalDefaultShippingPriceExpress'] = $dAmount; } + if (!isset($conf['oscPayPalSetVaulting'])) { + $conf['oscPayPalSetVaulting'] = false; + } return $conf; } diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php new file mode 100644 index 00000000..7238bab1 --- /dev/null +++ b/src/Controller/PayPalVaultingCardController.php @@ -0,0 +1,22 @@ +_aViewData['vaultingUserId'] = $this->getViewConfig()->getUserIdForVaulting(); + + return parent::render(); + } +} \ No newline at end of file diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php new file mode 100644 index 00000000..fe8dc00d --- /dev/null +++ b/src/Controller/PayPalVaultingController.php @@ -0,0 +1,22 @@ +_aViewData['vaultingUserId'] = $this->getViewConfig()->getUserIdForVaulting(); + + return parent::render(); + } +} \ No newline at end of file diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 6f20d5c4..5f57ad95 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Controller; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; @@ -37,6 +38,28 @@ public function render() $paymentService->removeTemporaryOrder(); } + if ($paypalCustomerId = $this->getUser()->getFieldData("oscpaypalcustomerid")) { + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { + $paymentType = key($vaultedPaymentTokens[0]["payment_source"]); + + $vaultedPaymentSources = []; + foreach ($vaultedPaymentTokens[0]["payment_source"] as $paymentSource) { + if ($paymentType == "card") { + $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); + $vaultedPaymentSources[$paymentType] = $paymentSource["brand"]." ".$string.$paymentSource["last_digits"]; + }elseif ($paymentType == "paypal") { + $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); + $vaultedPaymentSources[$paymentType] = $string." ".$paymentSource["email_address"]; + } + } + $this->addTplParam("vaultedPaymentSources", $vaultedPaymentSources); + } + } + + //reset vaulting session var + Registry::getSession()->deleteVariable("selectedVaultPaymentSourceIndex"); + return parent::render(); } @@ -115,9 +138,10 @@ public function getPaymentList() */ public function validatePayment() { + $request = Registry::getRequest(); $paymentService = $this->getServiceFromContainer(PaymentService::class); $actualPaymentId = $paymentService->getSessionPaymentId(); - $newPaymentId = Registry::getRequest()->getRequestParameter('paymentid'); + $newPaymentId = $request->getRequestParameter('paymentid'); // remove the possible exist paypal-payment, if we choose another if ( @@ -128,6 +152,12 @@ public function validatePayment() $paymentService->removeTemporaryOrder(); } + //if a vaulted payment was used, store its index in the session for using it in the next step + if (!is_null($paymentSourceIndex = $request->getRequestParameter("vaultingpaymentsource"))) { + Registry::getSession()->setVariable("selectedVaultPaymentSourceIndex", $paymentSourceIndex); + } + + return parent::validatePayment(); } diff --git a/src/Controller/VaultingTokenController.php b/src/Controller/VaultingTokenController.php new file mode 100644 index 00000000..68e7bb4b --- /dev/null +++ b/src/Controller/VaultingTokenController.php @@ -0,0 +1,94 @@ +getVaultingService(); + $card = (bool)Registry::get(Request::class)->getRequestEscapedParameter("card"); + $setupToken = $vaultingService->createVaultSetupToken($card); + + if ($this->storeSetupToken($setupToken["id"])) { + $this->outputJson($setupToken); + } + } + + /** + * Generate a Payment Token using a previously generated setup token + * @return void + */ + public function generatePaymentToken() + { + $vaultingService = $this->getVaultingService(); + $setupToken = Registry::getRequest()->getRequestParameter("token"); + + $paymentToken = $vaultingService->createVaultPaymentToken($setupToken); + if($this->storePayPalUserId($paymentToken["customer"]["id"])) { + $this->outputJson(["state" => "SUCCESS"]); + }else { + $this->outputJson(["state" => "ERROR"]); + } + } + + public function generateAccessTokenFromCustomerId($payPalCustomerId) + { + $vaultingService = $this->getVaultingService(); + + $this->outputJson($vaultingService->generateAccessTokenFromCustomerId($payPalCustomerId)); + } + + protected function getVaultingService() + { + if(!$this->vaultingService) { + $this->vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + } + + return $this->vaultingService; + } + + /** + * @param string $token + * @return bool + */ + protected function storeSetupToken($token) + { + $oUser = $this->getUser(); + $oUser->oxuser__oscpaypalvaultsetuptoken = new Field($token); + + return $oUser->save(); + } + + /** + * @param string $id + * @return bool + */ + protected function storePayPalUserId($id) + { + $user = $this->getUser(); + $user->oxuser__oscpaypalcustomerid = new Field($id); + + return $user->save(); + } + + /** + * Encodes and sends response as json + * + * @param $response + */ + protected function outputJson($response) + { + $utils = Registry::getUtils(); + $utils->setHeader('Content-Type: application/json; charset=utf-8'); + $utils->showMessageAndExit(json_encode($response)); + } +} \ No newline at end of file diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index dc20d0f5..59668b6a 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -32,6 +32,7 @@ public function generateUserIdToken($payPalCustomerId = false): array } $path = '/v1/oauth2/token'; + $method = 'post'; $response = $this->send('POST', $path, $params, $headers); $body = $response->getBody(); @@ -68,6 +69,7 @@ public function createVaultSetupToken(bool $card = false): array $headers = $this->getVaultingHeaders(); $path = '/v3/vault/setup-tokens'; + $method = 'post'; $response = $this->send( 'POST', @@ -175,6 +177,7 @@ public function createVaultPaymentToken($setupToken) $headers = $this->getVaultingHeaders(); $path = '/v3/vault/payment-tokens'; + $method = 'post'; $requestBody = [ "payment_source" => [ @@ -198,9 +201,12 @@ public function getVaultPaymentTokens($paypalCustomerId) return null; } - $path = '/v3/vault/payment-tokens?customer_id=' . $paypalCustomerId; + $headers = $this->getVaultingHeaders(); + + $path = '/v3/vault/payment-tokens?customer_id='.$paypalCustomerId; + $method = 'get'; - $response = $this->send('GET', $path); + $response = $this->send($method, $path, [], $headers); $body = $response->getBody(); return json_decode((string)$body, true); @@ -233,6 +239,7 @@ protected function getVaultingHeaders(): array { $headers = []; $headers['Content-Type'] = 'application/json'; + $headers['PayPal-Request-Id'] = time(); $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; $headers = array_merge($headers, $this->getAuthHeaders()); return $headers; diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index c1751a54..c7f625f7 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -19,6 +19,7 @@ use OxidEsales\Eshop\Application\Model\Country; use OxidEsales\Eshop\Application\Model\State; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Core\PayPalRequestAmountFactory; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; @@ -36,6 +37,7 @@ use OxidSolutionCatalysts\PayPalApi\Pui\ExperienceContext; use OxidSolutionCatalysts\PayPalApi\Pui\PuiPaymentSource; use OxidSolutionCatalysts\PayPalApi\Model\Orders\PaymentSource; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; /** * Class OrderRequestBuilder @@ -43,6 +45,7 @@ */ class OrderRequestFactory { + use ServiceContainer; /** * After you redirect the customer to the PayPal payment page, a Continue button appears. * Use this option when the final amount is not known when the checkout flow is initiated and you want to @@ -97,16 +100,16 @@ public function getRequest( if (!$paymentSource && $basket->getUser()) { $request->payer = $this->getPayer(); } - $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); + //todo test why this breaks vaulting if ($userAction || $returnUrl || $cancelUrl) { - $request->application_context = $this->getApplicationContext( - $userAction, - $returnUrl, - $cancelUrl, - $setProvidedAddress - ); +// $request->application_context = $this->getApplicationContext( +// $userAction, +// $returnUrl, +// $cancelUrl, +// $setProvidedAddress +// ); } if ($processingInstruction) { @@ -119,6 +122,13 @@ public function getRequest( $request->payment_source = $puiPaymentSource; } + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $setVaulting = $moduleSettings->getIsVaultingActive(); + + if($setVaulting) { + $this->modifyPaymentSourceForVaulting($request); + } + return $request; } @@ -562,4 +572,79 @@ protected function getPuiPaymentSource(): array return [PayPalDefinitions::PUI_REQUEST_PAYMENT_SOURCE_NAME => $paymentSource]; } + + /** + * @param OrderRequest $request + * @return void + */ + protected function modifyPaymentSourceForVaulting(OrderRequest $request): void + { + $config = Registry::getConfig(); + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + + $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); + + $card = Registry::getRequest()->getRequestParameter("fnc") == "createAcdcOrder"; + + //use selected vault + if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid")) { + + $paymentTokens = $vaultingService->getVaultPaymentTokens($payPalCustomerId); + //find out which payment token was selected by getting the index via request param + $selectedPaymentToken = $paymentTokens["payment_tokens"][$selectedVaultPaymentSourceIndex]; + $customerId = $selectedPaymentToken["customer"]["id"]; + + + $request->payment_source = + [ + "paypal" => + [ + "vault_id" => $selectedPaymentToken[0]["id"], + "attributes" => [ + "customer" => [ + "id" => $customerId + ] + ], + "experience_context" => + [ + "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', + "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', + "shipping_preference" => "SET_PROVIDED_ADDRESS", + ] + ] + ]; + } elseif ($config->getUser()) { + //save during purchase + if ($card) { + $newPaymentSource = $vaultingService->getPaymentSourceForVaulting(true); + $newPaymentSource["attributes"] = [ + "verification" => [ + "method" => "SCA_WHEN_REQUIRED" + ], + "vault" => [ + "store_in_vault" => "ON_SUCCESS" + ], + ]; + } else { + $newPaymentSource = [ + "paypal" => + [ + "attributes" => + [ + "vault" => + PayPalDefinitions::PAYMENT_VAULTING + ], + "experience_context" => + [ + "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', + "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', + "shipping_preference" => "SET_PROVIDED_ADDRESS", + ] + ], + ]; + } + + $request->payment_source = $newPaymentSource; + } + } } diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index e8023630..c48f6640 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -21,6 +21,14 @@ final class PayPalDefinitions public const SEPA_PAYPAL_PAYMENT_ID = 'oscpaypal_sepa'; public const CCALTERNATIVE_PAYPAL_PAYMENT_ID = 'oscpaypal_cc_alternative'; + //vaulting + public const PAYMENT_VAULTING = [ + "store_in_vault" => "ON_SUCCESS", + "usage_type" => "MERCHANT", + "customer_type" => "CONSUMER", + "permit_multiple_payment_tokens" => false, + ]; + private const PAYMENT_CONSTRAINTS_PAYPAL = [ 'oxfromamount' => 0.01, 'oxtoamount' => 60000, diff --git a/src/Core/ServiceFactory.php b/src/Core/ServiceFactory.php index f182421f..3c582de8 100644 --- a/src/Core/ServiceFactory.php +++ b/src/Core/ServiceFactory.php @@ -86,6 +86,17 @@ public function getTrackerService(): GenericService ); } + /** + * @return UserIdService + */ + public function getVaultingService(): VaultingService + { + return oxNew( + VaultingService::class, + $this->getClient() + ); + } + /** * @return Partner */ diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 663bc0c4..2b1c9930 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -94,6 +94,10 @@ public function isPayPalExpressPaymentEnabled(): bool return $this->getServiceFromContainer(ModuleSettings::class)->isPayPalCheckoutExpressPaymentEnabled(); } + public function getIsVaultingActive():bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); + } /** * @return Config @@ -243,6 +247,11 @@ protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): str if ($this->isPayPalBannerActive()) { $params['components'] .= ',messages'; } + + if($this->getIsVaultingActive()) { + $params['components'] .= ',card-fields'; + } + $params['locale'] = $localeCode; return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index d9006953..499741bc 100644 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -554,6 +554,11 @@ public function alwaysIgnoreSCAResult(): bool return $value === Constants::PAYPAL_SCA_DISABLED; } + public function getIsVaultingActive(): bool + { + return (bool)$this->getSettingValue('oscPayPalSetVaulting'); + } + /** * @return mixed */ diff --git a/src/Service/Payment.php b/src/Service/Payment.php index ac7be394..dafda9b5 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -11,6 +11,7 @@ use OxidEsales\Eshop\Application\Model\Basket as EshopModelBasket; use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\Exception\StandardException; +use OxidEsales\Eshop\Core\Field; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session as EshopSession; use OxidSolutionCatalysts\PayPal\Core\ConfirmOrderRequestFactory; @@ -602,7 +603,7 @@ public function doExecuteStandardPayment( throw PayPalException::sessionPaymentMalformedResponse(); } foreach ($response->links as $links) { - if ($links['rel'] === 'approve') { + if ($links['rel'] === 'approve' || $links['rel'] === 'payer-action') { $redirectLink = $links['href']; break; } diff --git a/translations/de/oscpaypal_de_lang.php b/translations/de/oscpaypal_de_lang.php index d98149d7..ef0efa4e 100644 --- a/translations/de/oscpaypal_de_lang.php +++ b/translations/de/oscpaypal_de_lang.php @@ -8,38 +8,54 @@ declare(strict_types=1); $aLang = [ - 'charset' => 'UTF-8', - 'OSC_PAYPAL_DESCRIPTION' => 'Zahlung bei %s', - 'OSC_PAYPAL_PAY_EXPRESS' => 'PayPal Express', - 'OSC_PAYPAL_PAY_PROCESSED' => 'Ihre Zahlung wird von PayPal verarbeitet.', - 'OSC_PAYPAL_PAY_UNLINK' => 'aufheben', - - 'OSC_PAYPAL_PAY_EXPRESS_ERROR_DELCOUNTRY' => 'Leider liefern wir nicht in Ihr gewünschtes Lieferland. Bitte wählen Sie eine andere Lieferadresse aus.', - 'OSC_PAYPAL_PAY_EXPRESS_ERROR_INPUTVALIDATION' => 'Leider kann PayPal nicht alle Adress-Pflichtfelder des Shops automatisch befüllen. Bitte legen Sie den Artikel in den Warenkorb, melden sich im Shop an und schließen die Bestellung dann mit PayPal ab.', - - 'OSC_PAYPAL_ACDC' => 'Advanced Credit and Debit Card', - 'OSC_PAYPAL_ACDC_CARD_NUMBER' => 'Kartennummer', - 'OSC_PAYPAL_ACDC_CARD_EXDATE' => 'Ablaufdatum', - 'OSC_PAYPAL_ACDC_CARD_CVV' => 'CVV', - 'OSC_PAYPAL_ACDC_CARD_NAME_ON_CARD' => 'Karteninhaber', - 'OSC_PAYPAL_ACDC_PLEASE_RETRY' => 'Bezahlvorgang wurde aus Sicherheitsgründen abgebrochen. Bitte geben Sie ihre Kreditkartendaten erneut ein und klicken einmal auf den Bestellbutton.', - - 'OSC_PAYPAL_VAT_CORRECTION' => 'Mwst. Korrektur', - - 'OSC_PAYPAL_PUI_HELP' => 'Für die Abwicklung des Rechnungskaufes benötigen wir Ihr Geburtsdatum sowie eine gültige Telefonnummer mit Orts- oder Ländervorwahl (z.B. 030 123456789 oder +49 30 123456789)', - 'OSC_PAYPAL_PUI_BIRTHDAY' => 'Geburtstag', - 'OSC_PAYPAL_PUI_BIRTHDAY_PLACEHOLDER' => '01.01.1970', - 'OSC_PAYPAL_PUI_PHONENUMBER' => 'Telefonnr.', - 'OSC_PAYPAL_PUI_PHONENUMBER_PLACEHOLDER' => '+49 30 123456789', - 'OSC_PAYPAL_PUI_PLEASE_RETRY' => 'Bitte geben Sie ihre Daten erneut ein.', - 'PAYPAL_PAYMENT_ERROR_PUI_GENRIC' => 'Validierung der Kundendaten für PayPal Rechnungskauf mit Ratepay fehlgeschlagen.', - 'PUI_PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED' => 'Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht für PayPal Rechnungskauf validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', - 'PUI_PAYMENT_SOURCE_DECLINED_BY_PROCESSOR' => 'Die gewählte Zahlungsart PayPal Rechnungskauf kann nicht genutzt werden. Diese Entscheidung basiert auf einem automatisierten Datenverarbeitungsverfahren. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', - 'PAYMENT_ERROR_INSTRUMENT_DECLINED' => 'Die gewählte Zahlart steht Ihnen bei PayPal nicht zur Verfügung.', + 'charset' => 'UTF-8', + 'OSC_PAYPAL_DESCRIPTION' => 'Zahlung bei %s', + 'OSC_PAYPAL_PAY_EXPRESS' => 'PayPal Express', + 'OSC_PAYPAL_PAY_PROCESSED' => 'Ihre Zahlung wird von PayPal verarbeitet.', + 'OSC_PAYPAL_PAY_UNLINK' => 'aufheben', + + 'OSC_PAYPAL_PAY_EXPRESS_ERROR_DELCOUNTRY' => 'Leider liefern wir nicht in Ihr gewünschtes Lieferland. Bitte wählen Sie eine andere Lieferadresse aus.', + 'OSC_PAYPAL_PAY_EXPRESS_ERROR_INPUTVALIDATION' => 'Leider kann PayPal nicht alle Adress-Pflichtfelder des Shops automatisch befüllen. Bitte legen Sie den Artikel in den Warenkorb, melden sich im Shop an und schließen die Bestellung dann mit PayPal ab.', + + 'OSC_PAYPAL_ACDC' => 'Advanced Credit and Debit Card', + 'OSC_PAYPAL_ACDC_CARD_NUMBER' => 'Kartennummer', + 'OSC_PAYPAL_ACDC_CARD_EXDATE' => 'Ablaufdatum', + 'OSC_PAYPAL_ACDC_CARD_CVV' => 'CVV', + 'OSC_PAYPAL_ACDC_CARD_NAME_ON_CARD' => 'Karteninhaber', + 'OSC_PAYPAL_ACDC_PLEASE_RETRY' => 'Bezahlvorgang wurde aus Sicherheitsgründen abgebrochen. Bitte geben Sie ihre Kreditkartendaten erneut ein und klicken einmal auf den Bestellbutton.', + + 'OSC_PAYPAL_VAT_CORRECTION' => 'Mwst. Korrektur', + + 'OSC_PAYPAL_PUI_HELP' => 'Für die Abwicklung des Rechnungskaufes benötigen wir Ihr Geburtsdatum sowie eine gültige Telefonnummer mit Orts- oder Ländervorwahl (z.B. 030 123456789 oder +49 30 123456789)', + 'OSC_PAYPAL_PUI_BIRTHDAY' => 'Geburtstag', + 'OSC_PAYPAL_PUI_BIRTHDAY_PLACEHOLDER' => '01.01.1970', + 'OSC_PAYPAL_PUI_PHONENUMBER' => 'Telefonnr.', + 'OSC_PAYPAL_PUI_PHONENUMBER_PLACEHOLDER' => '+49 30 123456789', + 'OSC_PAYPAL_PUI_PLEASE_RETRY' => 'Bitte geben Sie ihre Daten erneut ein.', + 'PAYPAL_PAYMENT_ERROR_PUI_GENRIC' => 'Validierung der Kundendaten für PayPal Rechnungskauf mit Ratepay fehlgeschlagen.', + 'PUI_PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED' => 'Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht für PayPal Rechnungskauf validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', + 'PUI_PAYMENT_SOURCE_DECLINED_BY_PROCESSOR' => 'Die gewählte Zahlungsart PayPal Rechnungskauf kann nicht genutzt werden. Diese Entscheidung basiert auf einem automatisierten Datenverarbeitungsverfahren. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay Kontaktformular.', + 'PAYMENT_ERROR_INSTRUMENT_DECLINED' => 'Die gewählte Zahlart steht Ihnen bei PayPal nicht zur Verfügung.', 'OSC_PAYPAL_ORDER_EXECUTION_IN_PROGRESS' => 'Ihre Bestellung wird geprüft, das kann bis zu 60 Sekunden dauern. Bitte kurz warten und dann erneut auf "zahlungspflichtig bestellen" klicken.', 'OSC_PAYPAL_LOG_IN_TO_CONTINUE' => 'Bitte loggen Sie sich ein, um die Bestellung abzuschliessen.', 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Die Sicherheitsüberprüfung ist fehlgeschlagen, bitte erneut versuchen.', 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Der Bezahlvorgang wurde abgebrochen.', 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'Der Warenkorb wurde geändert. Aus diesem Grund wurde der aktive PayPal-Zahlvorgang automatisch abgebrochen. Bitte starten Sie die Zahlung mit PayPal erneut. Es wurde noch kein Geld von PayPal eingezogen.', + 'OSC_PAYPAL_ORDER_EXECUTION_IN_PROGRESS' => 'Ihre Bestellung wird geprüft, das kann bis zu 60 Sekunden dauern. Bitte kurz warten und dann erneut auf "zahlungspflichtig bestellen" klicken.', + 'OSC_PAYPAL_LOG_IN_TO_CONTINUE' => 'Bitte loggen Sie sich ein, um die Bestellung abzuschliessen.', + 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Die Sicherheitsüberprüfung ist fehlgeschlagen, bitte erneut versuchen.', + 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Der Bezahlvorgang wurde abgebrochen.', + + 'OSC_PAYPAL_VAULTING_MENU' => 'PayPal Zahlart speichern', + 'OSC_PAYPAL_VAULTING_MENU_CARD' => 'PayPal Kreditkarte speichern', + 'OSC_PAYPAL_VAULTING_CARD_SAVE' => 'Karte speichern', + 'OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION' => 'Speichern Sie hier Ihre PayPal Zahlungsmethode für einen schnelleren Checkout.', + 'OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION_CARD' => 'Speichern Sie hier Ihre Karte für einen schnelleren Checkout.', + 'OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS' => 'Gespeicherte Zahlungsarten', + 'OSC_PAYPAL_VAULTING_ERROR' => 'Beim Speichern Ihrer Zahlart ist etwas schiefgelaufen.', + 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Ihre Zahlart wurde erfolgreich gespeichert.', + 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Weiter mit gespeicherter Zahlungsart', + 'OSC_PAYPAL_CARD_ENDING_IN' => 'endet mit ●●●', + 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal Zahlung mit', ]; diff --git a/translations/en/oscpaypal_en_lang.php b/translations/en/oscpaypal_en_lang.php index 4ab54c58..9f50ba45 100644 --- a/translations/en/oscpaypal_en_lang.php +++ b/translations/en/oscpaypal_en_lang.php @@ -43,4 +43,18 @@ 'OSC_PAYPAL_3DSECURITY_ERROR' => 'Security check failed, please retry.', 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Payment process could not be completed.', 'OSCPAYPAL_KILL_EXPRESS_SESSION_REASON' => 'The shopping cart has been changed. For this reason, the active PayPal payment process was automatically canceled. Please restart the payment with PayPal. No money has been collected from PayPal yet.', + 'OSC_PAYPAL_ORDEREXECUTION_ERROR' => 'Payment process could not be completed.', + + 'OSC_PAYPAL_VAULTING_MENU' => 'Save PayPal payment method', + 'OSC_PAYPAL_VAULTING_MENU_CARD' => 'Save PayPal card', + 'OSC_PAYPAL_VAULTING_CARD_SAVE' => 'Save card', + 'OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION' => 'Save your PayPal payment method here for a faster checkout.', + 'OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION_CARD' => 'Save your Card here for a faster checkout.', + 'OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS' => 'Saved payments', + 'OSC_PAYPAL_VAULTING_ERROR' => 'There was an error saving your payment method.', + 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Your payment method was saved successfully.', + 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Continue with saved payment method', + 'OSC_PAYPAL_CARD_ENDING_IN' => 'ending in ●●●', + 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal payment with', + ]; diff --git a/views/blocks/page/account/inc/account_menu.tpl b/views/blocks/page/account/inc/account_menu.tpl new file mode 100644 index 00000000..a99dd822 --- /dev/null +++ b/views/blocks/page/account/inc/account_menu.tpl @@ -0,0 +1,9 @@ +[{if $oViewConf->getIsVaultingActive()}] + + +[{/if}] +[{$smarty.block.parent}] \ No newline at end of file diff --git a/views/blocks/page/checkout/change_payment.tpl b/views/blocks/page/checkout/change_payment.tpl new file mode 100644 index 00000000..6ffb3048 --- /dev/null +++ b/views/blocks/page/checkout/change_payment.tpl @@ -0,0 +1,61 @@ +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+ [{foreach from=$vaultedPaymentSources item=paymentDescription name="paymentSources" key="paymentType"}] + [{assign var="iterator" value=$smarty.foreach.paymentSources.iteration-1}] + +
+
+
+ + +
+
+
+ [{/foreach}] + +
+ +
+
+
+ + +[{/if}] +[{if $oViewConf->isFlowCompatibleTheme()}] + [{include file='modules/osc/paypal/change_payment_flow.tpl'}] +[{else}] + [{include file='modules/osc/paypal/change_payment_wave.tpl'}] +[{/if}] +[{$smarty.block.parent}] diff --git a/views/blocks/page/checkout/thankyou.tpl b/views/blocks/page/checkout/thankyou.tpl new file mode 100644 index 00000000..ecbf776d --- /dev/null +++ b/views/blocks/page/checkout/thankyou.tpl @@ -0,0 +1,13 @@ +[{$smarty.block.parent}] + +[{if $oViewConf->getSessionVaultSuccess() !== null}] + [{if $oViewConf->getSessionVaultSuccess()}] +

+ [{oxmultilang ident="OSC_PAYPAL_VAULTING_SUCCESS"}] +

+ [{else}] +

+ [{oxmultilang ident="OSC_PAYPAL_VAULTING_ERROR"}] +

+ [{/if}] +[{/if}] \ No newline at end of file diff --git a/views/smarty/frontend/blocks/layout/base__base_js.tpl b/views/smarty/frontend/blocks/layout/base__base_js.tpl index a9d19f7f..82dcb6f1 100644 --- a/views/smarty/frontend/blocks/layout/base__base_js.tpl +++ b/views/smarty/frontend/blocks/layout/base__base_js.tpl @@ -8,8 +8,9 @@ ($className == 'details' && $oViewConf->showPayPalProductDetailsButton()) || ($className == 'basket' && $oViewConf->showPayPalBasketButton()) ) + && ($className !== 'oscaccountvaultcard') && ($className !== 'oscaccountvault') }] - + [{assign var="sCountryRestriction" value=$oViewConf->getCountryRestrictionForPayPalExpress()}] [{if $sCountryRestriction}] - [{elseif $className == 'payment'}] + [{elseif $className == 'payment' || $className == 'oscaccountvaultcard'}] + [{elseif $className == 'oscaccountvault'}] + [{elseif $oViewConf->isPayPalBannerActive() && ($className == 'start' || $className == 'search' || $className == 'details' || $className == 'alist' || $className == 'basket')}] [{/if}] diff --git a/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl b/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl new file mode 100644 index 00000000..dd757cc6 --- /dev/null +++ b/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl @@ -0,0 +1,102 @@ +[{capture append="oxidBlock_content"}] + [{assign var="template_title" value="OSC_PAYPAL_VAULTING_MENU_CARD"|oxmultilangassign}] + +

[{oxmultilang ident="OSC_PAYPAL_VAULTING_MENU_CARD"}]

+ +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION_CARD"}]

+
+
+ + +
+
+
+
+
+ +
+
+
+ + +
+ + [{include file="modules/osc/paypal/vaultedpaymentsources.tpl"}] + + [{insert name="oxid_tracker" title=$template_title}] +[{/capture}] + +[{capture append="oxidBlock_sidebar"}] + [{include file="page/account/inc/account_menu.tpl" active_link="oscPayPalVaultingCard"}] +[{/capture}] +[{include file="layout/page.tpl" sidebar="Left"}] \ No newline at end of file diff --git a/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl b/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl new file mode 100644 index 00000000..53d0b6de --- /dev/null +++ b/views/smarty/frontend/blocks/page/account/account_vaulting_paypal.tpl @@ -0,0 +1,65 @@ +[{capture append="oxidBlock_content"}] + [{assign var="template_title" value="OSC_PAYPAL_VAULTING_MENU"|oxmultilangassign}] + +

[{oxmultilang ident="OSC_PAYPAL_VAULTING_MENU"}]

+ +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_SAVE_INSTRUCTION"}]

+
+
+ + +
+
+
+ + + + [{include file="modules/osc/paypal/vaultedpaymentsources.tpl"}] + + [{insert name="oxid_tracker" title=$template_title}] +[{/capture}] + +[{capture append="oxidBlock_sidebar"}] + [{include file="page/account/inc/account_menu.tpl" active_link="oscPayPalVaulting"}] +[{/capture}] +[{include file="layout/page.tpl" sidebar="Left"}] \ No newline at end of file diff --git a/views/smarty/frontend/blocks/vaultedpaymentsources.tpl b/views/smarty/frontend/blocks/vaultedpaymentsources.tpl new file mode 100644 index 00000000..09df17a4 --- /dev/null +++ b/views/smarty/frontend/blocks/vaultedpaymentsources.tpl @@ -0,0 +1,23 @@ +[{assign var="vaultedPaymentSources" value=$oViewConf->getVaultPaymentTokens()}] + +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+
    + [{foreach from=$vaultedPaymentSources item=paymentToken}] + [{if $paymentToken.payment_source.card}] + [{assign var="brand" value=$paymentToken.payment_source.card.brand}] + [{assign var="lastdigits" value=$paymentToken.payment_source.card.last_digits}] +
  • [{$brand}] [{oxmultilang ident="OSC_PAYPAL_CARD_ENDING_IN"}][{$lastdigits}]
  • + [{elseif $paymentToken.payment_source.paypal}] + [{assign var="lastdigits" value=$paymentToken.payment_source.paypal.email_address}] +
  • [{oxmultilang ident="OSC_PAYPAL_CARD_PAYPAL_PAYMENT"}] [{$lastdigits}]
  • + [{/if}] + [{/foreach}] +
+
+
+[{/if}] \ No newline at end of file From 369f592667a0081e527fdc0499c5701ed9137be9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 09:14:57 +0000 Subject: [PATCH 002/265] Bump docker/metadata-action from 5.0.0 to 5.3.0 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.0.0 to 5.3.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/96383f45573cb7f253c731d3b3ab81c87ef81934...31cebacef4805868f9ce9a0cb03ee36c32df2ac4) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 6ccb459f..bdea7f41 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -67,7 +67,7 @@ jobs: # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 + uses: docker/metadata-action@31cebacef4805868f9ce9a0cb03ee36c32df2ac4 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From 0c3bb630bfa492f89fbe390ec78c9ebccc55d0dd Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:00:41 +0000 Subject: [PATCH 003/265] Update tag to v2.0.9 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 77e86d42..77989f50 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v1.0.9 \ No newline at end of file +v2.0.9 \ No newline at end of file From 96c3079094ec9f3047fb5a113b73cb376bddc3c6 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 08:02:50 +0000 Subject: [PATCH 004/265] Update tag to v1.0.9 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 77989f50..77e86d42 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.9 \ No newline at end of file +v1.0.9 \ No newline at end of file From fa5d2ef34114f796807245aa0b60b13391e6ce73 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 21 Dec 2023 15:23:19 +0100 Subject: [PATCH 005/265] PSPAYPAL-680 - fix success message in card vaulting --- .../frontend/blocks/page/account/account_vaulting_card.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl b/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl index dd757cc6..30f993c8 100644 --- a/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl +++ b/views/smarty/frontend/blocks/page/account/account_vaulting_card.tpl @@ -80,7 +80,7 @@ }); function showSuccessMessage() { - $('#PayPalButtonVaulting').hide(); + $('#payPalVaultingCardContainer').hide(); $('#PayPalVaultingSuccess').show(); } From 1c0896424d00244098757dc922c8c6ccdc43e9b0 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 21 Dec 2023 16:13:09 +0100 Subject: [PATCH 006/265] PSPAYPAL-680 - fix vaulted checkout for standard paypal + simplify requests --- src/Controller/OrderController.php | 35 +++++++++++- src/Core/Api/VaultingService.php | 4 +- src/Core/OrderRequestFactory.php | 54 ++++++++----------- src/Service/Payment.php | 21 ++++++++ .../page/checkout/shipping_and_payment.tpl | 54 +++++++++++++++++++ 5 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 views/tpl/flow/page/checkout/shipping_and_payment.tpl diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 70ec9c9c..74b698e6 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -15,6 +15,7 @@ use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; +use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; use OxidSolutionCatalysts\PayPal\Exception\Redirect; @@ -80,6 +81,28 @@ public function render() $paymentService->removeTemporaryOrder(); } + $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); + $config = Registry::getConfig(); + if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid")) { + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId,$selectedVaultPaymentSourceIndex); + //find out which payment token was selected by getting the index via request param + $paymentType = key($selectedPaymentToken["payment_source"]); + $paymentSource = $selectedPaymentToken["payment_source"][$paymentType]; + + $paymentDescription = ""; + if ($paymentType == "card") { + $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); + $paymentDescription = $paymentSource["brand"]." ".$string.$paymentSource["last_digits"]; + }elseif ($paymentType == "paypal") { + $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); + $paymentDescription = $string." ".$paymentSource["email_address"]; + } + + $this->addTplParam("vaultedPaymentDescription",$paymentDescription); + } + return parent::render(); } @@ -260,8 +283,10 @@ public function finalizepaypalsession(): string $standardRequestId = (string) Registry::getRequest()->getRequestParameter('token'); $sessionOrderId = Registry::getSession()->getVariable('sess_challenge'); $sessionCheckoutOrderId = PayPalSession::getCheckoutOrderId(); + $vaulting = Registry::getRequest()->getRequestParameter("vaulting"); - if (!$sessionOrderId || !$sessionCheckoutOrderId || ($standardRequestId !== $sessionCheckoutOrderId)) { + $cancelSession = !$sessionOrderId || !$sessionCheckoutOrderId || ($standardRequestId !== $sessionCheckoutOrderId); + if (!$vaulting && $cancelSession) { $this->cancelpaypalsession('request to session mismatch'); } @@ -270,7 +295,8 @@ public function finalizepaypalsession(): string /** @var PayPalApiModelOrder $payPalOrder */ $payPalOrder = $paymentService->fetchOrderFields((string) $sessionCheckoutOrderId, ''); - if ('APPROVED' !== $payPalOrder->status) { + $vaultingPaymentCompleted = $vaulting && $payPalOrder->status == "COMPLETED"; + if (!$vaultingPaymentCompleted && 'APPROVED' !== $payPalOrder->status) { throw PayPalException::sessionPaymentFail( 'Unexpected status ' . $payPalOrder->status . ' for PayPal order ' . $sessionCheckoutOrderId ); @@ -407,4 +433,9 @@ protected function getNextStep($success) // phpcs:ignore PSR2.Methods.MethodDecl return parent::getNextStep($success); } + + protected function addVaultedPaymentInfoToTpl() + { + + } } diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index 59668b6a..c6ecd97e 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -201,12 +201,10 @@ public function getVaultPaymentTokens($paypalCustomerId) return null; } - $headers = $this->getVaultingHeaders(); - $path = '/v3/vault/payment-tokens?customer_id='.$paypalCustomerId; $method = 'get'; - $response = $this->send($method, $path, [], $headers); + $response = $this->send($method, $path); $body = $response->getBody(); return json_decode((string)$body, true); diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index c7f625f7..52cc8b1f 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -96,20 +96,30 @@ public function getRequest( $request = $this->request = new OrderRequest(); $this->basket = $basket; + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $setVaulting = $moduleSettings->getIsVaultingActive(); + $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); + $useVaulting = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); + $request->intent = $intent; + $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); + + if($useVaulting) { + $this->modifyPaymentSourceForVaulting($request); + return $request; + } + if (!$paymentSource && $basket->getUser()) { $request->payer = $this->getPayer(); } - $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); - //todo test why this breaks vaulting if ($userAction || $returnUrl || $cancelUrl) { -// $request->application_context = $this->getApplicationContext( -// $userAction, -// $returnUrl, -// $cancelUrl, -// $setProvidedAddress -// ); + $request->application_context = $this->getApplicationContext( + $userAction, + $returnUrl, + $cancelUrl, + $setProvidedAddress + ); } if ($processingInstruction) { @@ -122,13 +132,6 @@ public function getRequest( $request->payment_source = $puiPaymentSource; } - $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - $setVaulting = $moduleSettings->getIsVaultingActive(); - - if($setVaulting) { - $this->modifyPaymentSourceForVaulting($request); - } - return $request; } @@ -360,9 +363,9 @@ public function getItems(): array public function getItemCategoryByBasketContent(): string { return ( - $this->basket->isEntirelyVirtualPayPalBasket() - ? Item::CATEGORY_DIGITAL_GOODS - : Item::CATEGORY_PHYSICAL_GOODS + $this->basket->isEntirelyVirtualPayPalBasket() + ? Item::CATEGORY_DIGITAL_GOODS + : Item::CATEGORY_PHYSICAL_GOODS ); } @@ -592,25 +595,12 @@ protected function modifyPaymentSourceForVaulting(OrderRequest $request): void $paymentTokens = $vaultingService->getVaultPaymentTokens($payPalCustomerId); //find out which payment token was selected by getting the index via request param $selectedPaymentToken = $paymentTokens["payment_tokens"][$selectedVaultPaymentSourceIndex]; - $customerId = $selectedPaymentToken["customer"]["id"]; - $request->payment_source = [ "paypal" => [ - "vault_id" => $selectedPaymentToken[0]["id"], - "attributes" => [ - "customer" => [ - "id" => $customerId - ] - ], - "experience_context" => - [ - "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', - "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', - "shipping_preference" => "SET_PROVIDED_ADDRESS", - ] + "vault_id" => $selectedPaymentToken["id"], ] ]; } elseif ($config->getUser()) { diff --git a/src/Service/Payment.php b/src/Service/Payment.php index dafda9b5..166d129e 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -25,6 +25,7 @@ use OxidSolutionCatalysts\PayPal\Exception\UserPhone as UserPhoneException; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalOrderModel; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings as ModuleSettingsService; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AuthorizationWithAdditionalData; use OxidSolutionCatalysts\PayPalApi\Model\Orders\ConfirmOrderRequest; @@ -41,6 +42,7 @@ class Payment { + use ServiceContainer; public const PAYMENT_ERROR_NONE = 'PAYPAL_PAYMENT_ERROR_NONE'; public const PAYMENT_ERROR_GENERIC = 'PAYPAL_PAYMENT_ERROR_GENERIC'; public const PAYMENT_ERROR_PUI_PHONE = 'PAYPAL_PAYMENT_ERROR_PUI_PHONE'; @@ -139,6 +141,19 @@ public function doCreatePayPalOrder( $response = []; + /* + * Set required request id if payer uses vaulted payment. + * The OXID order is not created yet, so a random id will be given. + */ + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $setVaulting = $moduleSettings->getIsVaultingActive(); + $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); + $useVaulting = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); + + if ($useVaulting) { + $payPalRequestId = time(); + } + try { $response = $orderService->createOrder( $request, @@ -608,6 +623,12 @@ public function doExecuteStandardPayment( break; } } + + //no customer interaction needed if a vaulted payment is used + if ($response->status === Constants::PAYPAL_STATUS_COMPLETED) { + return $returnUrl."&vaulting=true"; + } + if (!$redirectLink) { PayPalSession::unsetPayPalSession(); $this->removeTemporaryOrder(); diff --git a/views/tpl/flow/page/checkout/shipping_and_payment.tpl b/views/tpl/flow/page/checkout/shipping_and_payment.tpl new file mode 100644 index 00000000..0fb2cf4b --- /dev/null +++ b/views/tpl/flow/page/checkout/shipping_and_payment.tpl @@ -0,0 +1,54 @@ +[{assign var="sPaymentID" value=$payment->getId()}] +[{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] +
+
+
+ + +
+
+

+ [{oxmultilang ident="SHIPPING_CARRIER"}] + +

+
+
+ [{assign var="oShipSet" value=$oView->getShipSet()}] + [{$oShipSet->oxdeliveryset__oxtitle->value}] +
+
+
+
+
+
+
+

+ [{oxmultilang ident="PAYMENT_METHOD"}] + + + + + +

+
+
+ [{if $vaultedPaymentDescription}] + [{$vaultedPaymentDescription}] + [{elseif !$oscpaypal_executing_order}] + [{$payment->oxpayments__oxdesc->value}] + [{if $sPaymentID == "oscpaypal_acdc"}] + [{include file="modules/osc/paypal/acdc.tpl"}] + [{elseif $sPaymentID == "oscpaypal_pui"}] + [{include file="modules/osc/paypal/pui_flow.tpl"}] + [{/if}] + [{/if}] +
+
+
+
\ No newline at end of file From 4231df0707d7c824cd0a8d58e6e0c433f4bf97af Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Mon, 8 Jan 2024 16:41:51 +0100 Subject: [PATCH 007/265] PSPAYPAL-680 - add custom vaulting description for wave theme --- .../page/checkout/shipping_and_payment.tpl | 10 ++++ .../page/checkout/shipping_and_payment.tpl | 58 +++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 views/blocks/page/checkout/shipping_and_payment.tpl create mode 100644 views/tpl/wave/page/checkout/shipping_and_payment.tpl diff --git a/views/blocks/page/checkout/shipping_and_payment.tpl b/views/blocks/page/checkout/shipping_and_payment.tpl new file mode 100644 index 00000000..e972cc8e --- /dev/null +++ b/views/blocks/page/checkout/shipping_and_payment.tpl @@ -0,0 +1,10 @@ +[{assign var="payment" value=$oView->getPayment()}] +[{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal_pui" == $payment->getId() || $vaultedPaymentDescription}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/shipping_and_payment_flow.tpl"}] + [{else}] + [{include file="modules/osc/paypal/shipping_and_payment_wave.tpl"}] + [{/if}] +[{else}] + [{$smarty.block.parent}] +[{/if}] \ No newline at end of file diff --git a/views/tpl/wave/page/checkout/shipping_and_payment.tpl b/views/tpl/wave/page/checkout/shipping_and_payment.tpl new file mode 100644 index 00000000..98b0dcf6 --- /dev/null +++ b/views/tpl/wave/page/checkout/shipping_and_payment.tpl @@ -0,0 +1,58 @@ +[{assign var="sPaymentID" value=$payment->getId()}] +[{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] +
+
+
+ + +
+
+

+ [{oxmultilang ident="SHIPPING_CARRIER"}] + +

+
+
+ [{assign var="oShipSet" value=$oView->getShipSet()}] + [{$oShipSet->oxdeliveryset__oxtitle->value}] +
+
+
+
+
+
+
+
+

+ [{oxmultilang ident="PAYMENT_METHOD"}] + + + + + +

+
+
+ [{if $vaultedPaymentDescription}] + [{$vaultedPaymentDescription}] + [{elseif !$oscpaypal_executing_order}] + [{$payment->oxpayments__oxdesc->value}] + [{if $sPaymentID == "oscpaypal_acdc"}] + [{include file="modules/osc/paypal/acdc.tpl"}] + [{elseif $sPaymentID == "oscpaypal_pui"}] + [{include file="modules/osc/paypal/pui_wave.tpl"}] + [{/if}] + [{/if}] +
+
+
+
+
\ No newline at end of file From 5783d2ab6b1f68c61e66cb2ca5937f5c942befc1 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Tue, 9 Jan 2024 14:14:51 +0100 Subject: [PATCH 008/265] PSPAYPAL-680 - change order request for payment with vaulted ACDC --- src/Core/OrderRequestFactory.php | 45 ++++++++++++++++--- views/blocks/page/checkout/change_payment.tpl | 6 +-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 52cc8b1f..b0bf4431 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -105,7 +105,29 @@ public function getRequest( $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); if($useVaulting) { - $this->modifyPaymentSourceForVaulting($request); + $config = Registry::getConfig(); + $vaultingService = $this->getVaultingService(); + $payPalCustomerId = $this->getUsersPayPalCustomerId(); + + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId,$selectedVaultPaymentSourceIndex); + //find out which payment token was selected by getting the index via request param + $paymentType = key($selectedPaymentToken["payment_source"]); + $useCard = $paymentType == "card"; + + $this->modifyPaymentSourceForVaulting($request,$useCard); + + //we use the PayPal payment type as a "dummy payment" when we use vaulted payments. + //therefore, we need to use a returnURL depending on the payment type. + if ($useCard) { + $returnUrl = $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizeacdc'; + } + + $request->application_context = $this->getApplicationContext( + "", + $returnUrl, + $cancelUrl, + false + ); return $request; } @@ -580,17 +602,15 @@ protected function getPuiPaymentSource(): array * @param OrderRequest $request * @return void */ - protected function modifyPaymentSourceForVaulting(OrderRequest $request): void + protected function modifyPaymentSourceForVaulting(OrderRequest $request, $useCard = false): void { $config = Registry::getConfig(); - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + $vaultingService = $this->getVaultingService(); $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); - $card = Registry::getRequest()->getRequestParameter("fnc") == "createAcdcOrder"; - //use selected vault - if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid")) { + if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $this->getUsersPayPalCustomerId()) { $paymentTokens = $vaultingService->getVaultPaymentTokens($payPalCustomerId); //find out which payment token was selected by getting the index via request param @@ -605,7 +625,7 @@ protected function modifyPaymentSourceForVaulting(OrderRequest $request): void ]; } elseif ($config->getUser()) { //save during purchase - if ($card) { + if ($useCard) { $newPaymentSource = $vaultingService->getPaymentSourceForVaulting(true); $newPaymentSource["attributes"] = [ "verification" => [ @@ -637,4 +657,15 @@ protected function modifyPaymentSourceForVaulting(OrderRequest $request): void $request->payment_source = $newPaymentSource; } } + + private function getVaultingService() + { + return Registry::get(ServiceFactory::class)->getVaultingService(); + } + + private function getUsersPayPalCustomerId() + { + $config = Registry::getConfig(); + return $config->getUser()->getFieldData("oscpaypalcustomerid"); + } } diff --git a/views/blocks/page/checkout/change_payment.tpl b/views/blocks/page/checkout/change_payment.tpl index 6ffb3048..c8c58ff5 100644 --- a/views/blocks/page/checkout/change_payment.tpl +++ b/views/blocks/page/checkout/change_payment.tpl @@ -34,11 +34,7 @@ document.getElementById("paypalVaultCheckoutButton").onclick = function () { document.querySelectorAll(".vaulting_paymentsource").forEach(function (paymentsource) { if (paymentsource.checked) { - if (paymentsource.dataset.paymenttype === "paypal") { - document.getElementById("payment_oscpaypal").click(); - }else { - document.getElementById("payment_oscpaypal_acdc").click(); - } + document.getElementById("payment_oscpaypal").click(); let input = document.createElement("input"); input.type = "hidden"; From cef6858bc65b5ab315a4285cf49eceef3021828d Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Wed, 10 Jan 2024 20:32:14 +0100 Subject: [PATCH 009/265] PSPAYPAL-680 - add button to chose whether or not the payment shall be saved --- src/Controller/OrderController.php | 6 ------ src/Core/OrderRequestFactory.php | 11 +++++++++-- .../checkout_order_btn_submit_bottom.tpl | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 74b698e6..9005b9a2 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -379,7 +379,6 @@ public function cancelpaypalsession(string $errorcode = null): string */ public function getPayPalPuiFraudnetCmId(): string { - if (!($cmId = PayPalSession::getPayPalPuiCmId())) { $cmId = Registry::getUtilsObject()->generateUId(); PayPalSession::storePayPalPuiCmId($cmId); @@ -433,9 +432,4 @@ protected function getNextStep($success) // phpcs:ignore PSR2.Methods.MethodDecl return parent::getNextStep($success); } - - protected function addVaultedPaymentInfoToTpl() - { - - } } diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index b0bf4431..7bc730af 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -99,12 +99,12 @@ public function getRequest( $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $setVaulting = $moduleSettings->getIsVaultingActive(); $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); - $useVaulting = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); $request->intent = $intent; $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); - if($useVaulting) { + $useVaultedPayment = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); + if($useVaultedPayment) { $config = Registry::getConfig(); $vaultingService = $this->getVaultingService(); $payPalCustomerId = $this->getUsersPayPalCustomerId(); @@ -128,6 +128,13 @@ public function getRequest( $cancelUrl, false ); + return $request; + }elseif (Registry::getRequest()->getRequestParameter("vaultPayment")) { + $paymentType = Registry::getRequest()->getRequestParameter("oscPayPalPaymentTypeForVaulting"); + $card = $paymentType == PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; + + $this->modifyPaymentSourceForVaulting($request, $card); + return $request; } diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl new file mode 100644 index 00000000..c9e3d0d0 --- /dev/null +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -0,0 +1,16 @@ +[{assign var="payment" value=$oView->getPayment()}] +[{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal" == $payment->getId()}] +
+ + + +
+[{/if}] +[{if "oscpaypal_pui" == $payment->getId()}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/checkout_order_btn_submit_bottom_flow.tpl"}] + [{else}] + [{include file="modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl"}] + [{/if}] +[{/if}] +[{$smarty.block.parent}] \ No newline at end of file From 5e3fd1366560766a36e9e3473f93a619ec4c4ad6 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 11 Jan 2024 10:24:45 +0100 Subject: [PATCH 010/265] PSPAYPAL-680 - add lang --- translations/de/oscpaypal_de_lang.php | 1 + translations/en/oscpaypal_en_lang.php | 1 + views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/translations/de/oscpaypal_de_lang.php b/translations/de/oscpaypal_de_lang.php index ef0efa4e..b3160658 100644 --- a/translations/de/oscpaypal_de_lang.php +++ b/translations/de/oscpaypal_de_lang.php @@ -55,6 +55,7 @@ 'OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS' => 'Gespeicherte Zahlungsarten', 'OSC_PAYPAL_VAULTING_ERROR' => 'Beim Speichern Ihrer Zahlart ist etwas schiefgelaufen.', 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Ihre Zahlart wurde erfolgreich gespeichert.', + 'OSC_PAYPAL_VAULTING_SAVE' => 'Zahlart speichern', 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Weiter mit gespeicherter Zahlungsart', 'OSC_PAYPAL_CARD_ENDING_IN' => 'endet mit ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal Zahlung mit', diff --git a/translations/en/oscpaypal_en_lang.php b/translations/en/oscpaypal_en_lang.php index 9f50ba45..8d42f8eb 100644 --- a/translations/en/oscpaypal_en_lang.php +++ b/translations/en/oscpaypal_en_lang.php @@ -53,6 +53,7 @@ 'OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS' => 'Saved payments', 'OSC_PAYPAL_VAULTING_ERROR' => 'There was an error saving your payment method.', 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Your payment method was saved successfully.', + 'OSC_PAYPAL_VAULTING_SAVE' => 'Save payment', 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Continue with saved payment method', 'OSC_PAYPAL_CARD_ENDING_IN' => 'ending in ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal payment with', diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index c9e3d0d0..e168318a 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -3,7 +3,7 @@
- +
[{/if}] [{if "oscpaypal_pui" == $payment->getId()}] From 1a4f865ed50c22388dbdfad9fb2420a4a08a5a13 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Sat, 9 Dec 2023 10:43:12 +0100 Subject: [PATCH 011/265] PayPal-Log consider Shop-ErrorLogLevel --- src/Controller/Admin/PayPalOrderController.php | 1 + src/Controller/OrderController.php | 1 + src/Controller/WebhookController.php | 1 + src/Core/Config.php | 13 +++++++++++++ src/Core/Tracker/Tracker.php | 1 + .../Handler/CheckoutOrderApprovedHandler.php | 1 + .../Handler/PaymentCaptureCompletedHandler.php | 1 + src/Core/Webhook/Handler/WebhookHandlerBase.php | 1 + src/Core/Webhook/RequestHandler.php | 1 + src/Model/PaymentGateway.php | 1 + src/Service/ModuleSettings.php | 1 + src/Service/Payment.php | 10 ++++++++++ 12 files changed, 33 insertions(+) diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index b2fa199f..1a15e9dc 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -11,6 +11,7 @@ use OxidEsales\Eshop\Application\Model\Order; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelPayPalOrder; diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 9005b9a2..74f4ac61 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -11,6 +11,7 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\DisplayError; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; diff --git a/src/Controller/WebhookController.php b/src/Controller/WebhookController.php index 5a7251bb..8330694c 100644 --- a/src/Controller/WebhookController.php +++ b/src/Controller/WebhookController.php @@ -9,6 +9,7 @@ use OxidEsales\Eshop\Application\Component\Widget\WidgetController; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\RequestReader; use OxidSolutionCatalysts\PayPal\Core\Webhook\EventDispatcher; diff --git a/src/Core/Config.php b/src/Core/Config.php index d8a1611f..29817e64 100644 --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -435,4 +435,17 @@ public function getIsVaultingActive(): bool { return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); } + + public function isLogLevel(string $level): bool + { + $possiblePayPalLevels = [ + 'error' => 400, + 'info' => 200, + 'debug' => 100 + ]; + $logLevel = Registry::getConfig()->getConfigParam('sLogLevel') ?? 'error'; + $logLevel = isset($possiblePayPalLevels[$logLevel]) ? $logLevel : 'error'; + $level = isset($possiblePayPalLevels[$level]) ? $level : 'error'; + return $possiblePayPalLevels[$logLevel] <= $possiblePayPalLevels[$level]; + } } diff --git a/src/Core/Tracker/Tracker.php b/src/Core/Tracker/Tracker.php index 8954852a..0e93775c 100644 --- a/src/Core/Tracker/Tracker.php +++ b/src/Core/Tracker/Tracker.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Tracker; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index a8d3d0db..48b3290a 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -12,6 +12,7 @@ use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelOrder; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Capture; diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index b7e3cba8..be422dba 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook\Handler; use OxidEsales\EshopCommunity\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiModelOrder; diff --git a/src/Core/Webhook/Handler/WebhookHandlerBase.php b/src/Core/Webhook/Handler/WebhookHandlerBase.php index 50f1341f..8e4687ef 100644 --- a/src/Core/Webhook/Handler/WebhookHandlerBase.php +++ b/src/Core/Webhook/Handler/WebhookHandlerBase.php @@ -12,6 +12,7 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Service\Logger; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Webhook\Event; use OxidSolutionCatalysts\PayPal\Exception\NotFound; use OxidSolutionCatalysts\PayPal\Exception\WebhookEventException; diff --git a/src/Core/Webhook/RequestHandler.php b/src/Core/Webhook/RequestHandler.php index b97a8e75..b1ea1c15 100644 --- a/src/Core/Webhook/RequestHandler.php +++ b/src/Core/Webhook/RequestHandler.php @@ -10,6 +10,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook; use JsonException; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\RequestReader; use OxidSolutionCatalysts\PayPal\Core\Webhook\EventDispatcher as WebhookDispatcher; diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index 9b1bd9fb..eb174784 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -11,6 +11,7 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\Registry; use OxidSolutionCatalysts\PayPal\Service\Logger; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 499741bc..4ec80692 100644 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -18,6 +18,7 @@ use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ModuleConfiguration; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Exception\ModuleSettingNotFountException; use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Module; diff --git a/src/Service/Payment.php b/src/Service/Payment.php index 166d129e..e8506a0e 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -14,6 +14,7 @@ use OxidEsales\Eshop\Core\Field; use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session as EshopSession; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\ConfirmOrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; @@ -124,6 +125,8 @@ public function doCreatePayPalOrder( $order instanceof EshopModelOrder ?? $order->setOrderNumber(); /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); + /** @var Config $payPalConfig */ + $payPalConfig = oxNew(Config::class); $request = $this->orderRequestFactory->getRequest( $basket, @@ -349,6 +352,11 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); $this->logger->log('debug', $exception->getMessage(), [$exception]); + /** @var Config $payPalConfig */ + $payPalConfig = oxNew(Config::class); + if ($payPalConfig->isLogLevel('error')) { + $this->moduleLogger->error($exception->getMessage(), [$exception]); + } throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } } else { @@ -666,6 +674,8 @@ public function doExecutePuiPayment( string $payPalClientMetadataId = '' ): bool { $this->setPaymentExecutionError(self::PAYMENT_ERROR_NONE); + /** @var Config $payPalConfig */ + $payPalConfig = oxNew(Config::class); try { $result = $this->doCreatePayPalOrder( From 2591c1862fc9e1655a48e636d2fb5cb4a836fd38 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Sat, 9 Dec 2023 10:45:02 +0100 Subject: [PATCH 012/265] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09fa3956..4c58068b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support +## [2.3.4] - 2023-??-?? + +- PayPal-Log consider Shop-ErrorLogLevel + ## [2.3.3] - 2023-11-16 - [0007549](https://bugs.oxid-esales.com/view.php?id=7549): Optional field in shop admin -> refund "Note to buyer" is transmitted to PayPal From 8eb921d643629fc1b2af4ca547b6598657513dcc Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Sat, 9 Dec 2023 11:36:07 +0100 Subject: [PATCH 013/265] change Debug-Level on Capture --- src/Service/Payment.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/Payment.php b/src/Service/Payment.php index e8506a0e..f3e65782 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -354,8 +354,8 @@ public function doCapturePayPalOrder( $this->logger->log('debug', $exception->getMessage(), [$exception]); /** @var Config $payPalConfig */ $payPalConfig = oxNew(Config::class); - if ($payPalConfig->isLogLevel('error')) { - $this->moduleLogger->error($exception->getMessage(), [$exception]); + if ($payPalConfig->isLogLevel('debug')) { + $this->moduleLogger->debug($exception->getMessage(), [$exception]); } throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } From 39ab36a7f53a13f76552201f104143ffca286fd6 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 14 Dec 2023 16:24:28 +0100 Subject: [PATCH 014/265] WIP: simplify Logger --- .../Admin/PayPalOrderController.php | 9 +++- src/Controller/OrderController.php | 2 - src/Controller/ProxyController.php | 8 ++-- src/Controller/WebhookController.php | 1 - src/Core/Logger.php | 47 +++++++++++++++++++ src/Core/Onboarding/Onboarding.php | 22 +++++++-- src/Core/Tracker/Tracker.php | 1 - .../PaymentCaptureCompletedHandler.php | 8 +++- .../Webhook/Handler/WebhookHandlerBase.php | 1 + src/Model/Order.php | 4 +- src/Model/PaymentGateway.php | 4 +- src/Service/ModuleSettings.php | 2 +- src/Service/Payment.php | 31 +++++++++--- 13 files changed, 115 insertions(+), 25 deletions(-) create mode 100644 src/Core/Logger.php diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index 1a15e9dc..492facc8 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -11,7 +11,7 @@ use OxidEsales\Eshop\Application\Model\Order; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelPayPalOrder; @@ -94,6 +94,10 @@ public function executeFunction($functionName) parent::executeFunction($functionName); } catch (ApiException $exception) { $this->addTplParam('error', $exception->getErrorDescription()); + + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', $exception->getMessage()); } } @@ -154,6 +158,9 @@ public function render() } } catch (ApiException $exception) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_ERROR_' . $exception->getErrorIssue())); + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', $exception->getMessage()); } } elseif ( $order->getFieldData('oxpaymenttype') == $this->payPalPlusPaymentType && diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 74f4ac61..cb44fcd6 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -11,7 +11,6 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\DisplayError; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; @@ -27,7 +26,6 @@ use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiModelOrder; -use Psr\Log\LoggerInterface; /** * Class OrderController diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 29ce466b..cb6ba2b1 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -21,16 +21,16 @@ use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface; use OxidSolutionCatalysts\PayPal\Module; use OxidSolutionCatalysts\PayPal\Service\Logger; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Constants; +use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; +use OxidSolutionCatalysts\PayPal\Service\UserRepository; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; -use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; -use OxidSolutionCatalysts\PayPal\Service\UserRepository; -use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiOrder; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; diff --git a/src/Controller/WebhookController.php b/src/Controller/WebhookController.php index 8330694c..5a7251bb 100644 --- a/src/Controller/WebhookController.php +++ b/src/Controller/WebhookController.php @@ -9,7 +9,6 @@ use OxidEsales\Eshop\Application\Component\Widget\WidgetController; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\RequestReader; use OxidSolutionCatalysts\PayPal\Core\Webhook\EventDispatcher; diff --git a/src/Core/Logger.php b/src/Core/Logger.php new file mode 100644 index 00000000..89428646 --- /dev/null +++ b/src/Core/Logger.php @@ -0,0 +1,47 @@ + 400, + 'info' => 200, + 'debug' => 100 + ]; + + public function log(string $level, string $message, array $exception = []): void + { + /** @var LoggerInterface $logger */ + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Logger'); + + if ($this->isLogLevel($level)) { + $logger->{$level}($message, $exception); + } + } + + public function isLogLevel(string $level): bool + { + + $logLevel = Registry::getConfig()->getConfigParam('sLogLevel') ?? 'error'; + $logLevel = isset($possiblePayPalLevels[$logLevel]) ? $logLevel : 'error'; + $level = isset($possiblePayPalLevels[$level]) ? $level : 'error'; + return $this->possiblePayPalLevels[$logLevel] <= $this->possiblePayPalLevels[$level]; + } +} diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index c2be8cfd..8ebb59a1 100644 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -8,12 +8,14 @@ namespace OxidSolutionCatalysts\PayPal\Core\Onboarding; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; use OxidSolutionCatalysts\PayPal\Core\PartnerConfig; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Exception\OnboardingException; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; +use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Onboarding as ApiOnboardingClient; use Psr\Log\LoggerInterface; @@ -52,11 +54,18 @@ public function fetchCredentials(): array $nonce = Registry::getSession()->getVariable('PAYPAL_MODULE_NONCE'); Registry::getSession()->deleteVariable('PAYPAL_MODULE_NONCE'); + try { /** @var ApiOnboardingClient $apiClient */ $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox']); $apiClient->authAfterWebLogin($onboardingResponse['authCode'], $onboardingResponse['sharedId'], $nonce); $credentials = $apiClient->getCredentials(); + $credentials = $apiClient->getCredentials(); + } catch (ApiException $exception) { + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', $exception->getMessage(), [$exception]); + } return $credentials; } @@ -143,9 +152,16 @@ public function getOnboardingClient(bool $isSandbox, bool $withCredentials = fal public function fetchMerchantInformations(): array { $onboardingResponse = $this->getOnboardingPayload(); - /** @var ApiOnboardingClient $apiClient */ - $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox'], true); - return $apiClient->getMerchantInformations(); + try { + /** @var ApiOnboardingClient $apiClient */ + $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox'], true); + $merchantInformations = $apiClient->getMerchantInformations(); + } catch (ApiException $exception) { + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', $exception->getMessage(), [$exception]); + } + return $merchantInformations; } public function saveEligibility(array $merchantInformations): array diff --git a/src/Core/Tracker/Tracker.php b/src/Core/Tracker/Tracker.php index 0e93775c..8954852a 100644 --- a/src/Core/Tracker/Tracker.php +++ b/src/Core/Tracker/Tracker.php @@ -8,7 +8,6 @@ namespace OxidSolutionCatalysts\PayPal\Core\Tracker; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index be422dba..36ce90a3 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -8,7 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook\Handler; use OxidEsales\EshopCommunity\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiModelOrder; @@ -41,6 +41,12 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel ->getOrderService() ->showOrderDetails($payPalOrderId, ''); } catch (ApiException $exception) { + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('debug', + 'Exception during PaymentCaptureCompletedHandler::getPayPalOrderDetails().', + [$exception] + ); $apiOrder = null; } diff --git a/src/Core/Webhook/Handler/WebhookHandlerBase.php b/src/Core/Webhook/Handler/WebhookHandlerBase.php index 8e4687ef..a8e806f4 100644 --- a/src/Core/Webhook/Handler/WebhookHandlerBase.php +++ b/src/Core/Webhook/Handler/WebhookHandlerBase.php @@ -75,6 +75,7 @@ public function handle(Event $event): void } //Webhook is used to trigger unfinished order cleanup at the end of each webhook handle. + //TODO: check if webhook handler really is the place place for this $this->cleanUpNotFinishedOrders(); } diff --git a/src/Model/Order.php b/src/Model/Order.php index 88142319..988182cc 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -19,13 +19,13 @@ use OxidEsales\Eshop\Core\Field; use OxidEsales\Eshop\Core\Model\BaseModel; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; -use OxidSolutionCatalysts\PayPal\Core\Tracker\Tracker; +use OxidSolutionCatalysts\PayPal\Core\Tracker\TrackerTracker; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\OrderRepository; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index eb174784..a293fad3 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -76,7 +76,7 @@ protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool $shopOrderId = (string)$order->getFieldData('oxordernr'); $paymentService->doPatchPayPalOrder($basket, $checkoutOrderId, $shopOrderId); } catch (Exception $exception) { - $logger->log('error', 'Error on order patch call.', [$exception]); + $logger->log('error','Error on order patch call.', [$exception]); } // Capture Order @@ -87,7 +87,7 @@ protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool // success means at this point, that we triggered the capture without errors $success = true; } catch (Exception $exception) { - $logger->log('error', 'Error on order capture call.', [$exception]); + $logger->log('error','Error on order capture call.', [$exception]); } // destroy PayPal-Session diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 4ec80692..2a92d04c 100644 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -18,7 +18,7 @@ use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ModuleConfiguration; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Exception\ModuleSettingNotFountException; use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; -use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Module; diff --git a/src/Service/Payment.php b/src/Service/Payment.php index f3e65782..dce53d2c 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -15,6 +15,7 @@ use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session as EshopSession; use OxidSolutionCatalysts\PayPal\Core\Config; +use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\ConfirmOrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; @@ -125,8 +126,8 @@ public function doCreatePayPalOrder( $order instanceof EshopModelOrder ?? $order->setOrderNumber(); /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); - /** @var Config $payPalConfig */ - $payPalConfig = oxNew(Config::class); + /** @var Logger $logger */ + $logger = oxNew(Logger::class); $request = $this->orderRequestFactory->getRequest( $basket, @@ -166,8 +167,14 @@ public function doCreatePayPalOrder( $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null, ); } catch (ApiException $exception) { + $logger->log( + 'error', + 'Api error on order create call. ' . $exception->getErrorIssue(), + [$exception] + ); $this->handlePayPalApiError($exception); } catch (Exception $exception) { + $logger->log('error', 'Error on order create call.', [$exception]); $this->setPaymentExecutionError(self::PAYMENT_ERROR_GENERIC); } @@ -235,6 +242,9 @@ public function doPatchPayPalOrder( Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (Exception $exception) { + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', 'Error on order patch call.', [$exception]); throw $exception; } } @@ -260,6 +270,8 @@ public function doCapturePayPalOrder( $paymentService = Registry::get(ServiceFactory::class)->getPaymentService(); /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); + /** @var Logger $logger */ + $logger = oxNew(Logger::class); // Capture Order try { @@ -317,6 +329,7 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); + $logger->log('error', $exception->getMessage(), [$exception]); throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } @@ -351,11 +364,10 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); - $this->logger->log('debug', $exception->getMessage(), [$exception]); /** @var Config $payPalConfig */ $payPalConfig = oxNew(Config::class); if ($payPalConfig->isLogLevel('debug')) { - $this->moduleLogger->debug($exception->getMessage(), [$exception]); + $this->logger->log('debug', $exception->getMessage(), [$exception]); } throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } @@ -574,6 +586,10 @@ public function doExecuteUAPMPayment(EshopModelOrder $order, EshopModelBasket $b } catch (Exception $exception) { PayPalSession::unsetPayPalOrderId(); $this->removeTemporaryOrder(); + //TODO: do we need to log this? + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', $exception->getMessage(), [$exception]); } //NOTE: payment not fully executed, we need customer interaction first @@ -674,8 +690,6 @@ public function doExecutePuiPayment( string $payPalClientMetadataId = '' ): bool { $this->setPaymentExecutionError(self::PAYMENT_ERROR_NONE); - /** @var Config $payPalConfig */ - $payPalConfig = oxNew(Config::class); try { $result = $this->doCreatePayPalOrder( @@ -699,11 +713,14 @@ public function doExecutePuiPayment( $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_PHONE); } catch (Exception $exception) { $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_GENERIC); + /** @var Logger $logger */ + $logger = oxNew(Logger::class); + $logger->log('error', 'Error on pui order creation call.', [$exception]); } # TODO: check what we created, ensure it is a pui order # $paymentSource = $this->fetchOrderFields((string) $payPalOrderId, 'payment_source'); - # $this->logger->log('error', serialize($paymentSource)); + # $logger->log('error', serialize($paymentSource)); if (!$payPalOrderId) { return false; From a4952ce82f4a47587d68b355d6d3da8f063cd053 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 15 Dec 2023 17:06:10 +0100 Subject: [PATCH 015/265] use Logger as Service --- .../Admin/PayPalOrderController.php | 6 +-- src/Controller/ProxyController.php | 1 - src/Core/Logger.php | 47 ------------------- src/Core/Onboarding/Onboarding.php | 6 +-- .../Handler/CheckoutOrderApprovedHandler.php | 1 - .../PaymentCaptureCompletedHandler.php | 4 +- .../Webhook/Handler/WebhookHandlerBase.php | 1 - src/Core/Webhook/RequestHandler.php | 1 - src/Model/Order.php | 3 +- src/Model/PaymentGateway.php | 1 - src/Service/ModuleSettings.php | 1 - src/Service/Payment.php | 25 +++------- 12 files changed, 17 insertions(+), 80 deletions(-) delete mode 100644 src/Core/Logger.php diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index 492facc8..fe5a15a0 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -11,7 +11,7 @@ use OxidEsales\Eshop\Application\Model\Order; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Logger; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelPayPalOrder; @@ -96,7 +96,7 @@ public function executeFunction($functionName) $this->addTplParam('error', $exception->getErrorDescription()); /** @var Logger $logger */ - $logger = oxNew(Logger::class); + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); $logger->log('error', $exception->getMessage()); } } @@ -159,7 +159,7 @@ public function render() } catch (ApiException $exception) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_ERROR_' . $exception->getErrorIssue())); /** @var Logger $logger */ - $logger = oxNew(Logger::class); + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); $logger->log('error', $exception->getMessage()); } } elseif ( diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index cb6ba2b1..9ddb502b 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -25,7 +25,6 @@ use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPal\Service\UserRepository; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; diff --git a/src/Core/Logger.php b/src/Core/Logger.php deleted file mode 100644 index 89428646..00000000 --- a/src/Core/Logger.php +++ /dev/null @@ -1,47 +0,0 @@ - 400, - 'info' => 200, - 'debug' => 100 - ]; - - public function log(string $level, string $message, array $exception = []): void - { - /** @var LoggerInterface $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Logger'); - - if ($this->isLogLevel($level)) { - $logger->{$level}($message, $exception); - } - } - - public function isLogLevel(string $level): bool - { - - $logLevel = Registry::getConfig()->getConfigParam('sLogLevel') ?? 'error'; - $logLevel = isset($possiblePayPalLevels[$logLevel]) ? $logLevel : 'error'; - $level = isset($possiblePayPalLevels[$level]) ? $level : 'error'; - return $this->possiblePayPalLevels[$logLevel] <= $this->possiblePayPalLevels[$level]; - } -} diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index 8ebb59a1..245a9936 100644 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -8,7 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Onboarding; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Logger; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; use OxidSolutionCatalysts\PayPal\Core\PartnerConfig; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; @@ -63,7 +63,7 @@ public function fetchCredentials(): array $credentials = $apiClient->getCredentials(); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = oxNew(Logger::class); + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); $logger->log('error', $exception->getMessage(), [$exception]); } @@ -158,7 +158,7 @@ public function fetchMerchantInformations(): array $merchantInformations = $apiClient->getMerchantInformations(); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = oxNew(Logger::class); + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); $logger->log('error', $exception->getMessage(), [$exception]); } return $merchantInformations; diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index 48b3290a..a8d3d0db 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -12,7 +12,6 @@ use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Model\PayPalOrder as PayPalModelOrder; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Capture; diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index 36ce90a3..41eb9674 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -8,7 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook\Handler; use OxidEsales\EshopCommunity\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Logger; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiModelOrder; @@ -42,7 +42,7 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel ->showOrderDetails($payPalOrderId, ''); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = oxNew(Logger::class); + $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); $logger->log('debug', 'Exception during PaymentCaptureCompletedHandler::getPayPalOrderDetails().', [$exception] diff --git a/src/Core/Webhook/Handler/WebhookHandlerBase.php b/src/Core/Webhook/Handler/WebhookHandlerBase.php index a8e806f4..5de1d2e5 100644 --- a/src/Core/Webhook/Handler/WebhookHandlerBase.php +++ b/src/Core/Webhook/Handler/WebhookHandlerBase.php @@ -12,7 +12,6 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Service\Logger; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Webhook\Event; use OxidSolutionCatalysts\PayPal\Exception\NotFound; use OxidSolutionCatalysts\PayPal\Exception\WebhookEventException; diff --git a/src/Core/Webhook/RequestHandler.php b/src/Core/Webhook/RequestHandler.php index b1ea1c15..b97a8e75 100644 --- a/src/Core/Webhook/RequestHandler.php +++ b/src/Core/Webhook/RequestHandler.php @@ -10,7 +10,6 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook; use JsonException; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\RequestReader; use OxidSolutionCatalysts\PayPal\Core\Webhook\EventDispatcher as WebhookDispatcher; diff --git a/src/Model/Order.php b/src/Model/Order.php index 988182cc..228a21c5 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -19,13 +19,14 @@ use OxidEsales\Eshop\Core\Field; use OxidEsales\Eshop\Core\Model\BaseModel; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; +use OxidSolutionCatalysts\PayPal\Core\Tracker\Tracker; use OxidSolutionCatalysts\PayPal\Core\Tracker\TrackerTracker; use OxidSolutionCatalysts\PayPal\Exception\PayPalException; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\OrderRepository; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index a293fad3..f295b547 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -11,7 +11,6 @@ use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\Registry; use OxidSolutionCatalysts\PayPal\Service\Logger; -use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 2a92d04c..499741bc 100644 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -18,7 +18,6 @@ use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\DataObject\ModuleConfiguration; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Exception\ModuleSettingNotFountException; use OxidEsales\EshopCommunity\Internal\Transition\Utility\ContextInterface; -use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Module; diff --git a/src/Service/Payment.php b/src/Service/Payment.php index dce53d2c..10c14554 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -15,7 +15,6 @@ use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\Session as EshopSession; use OxidSolutionCatalysts\PayPal\Core\Config; -use OxidSolutionCatalysts\PayPal\Core\Logger; use OxidSolutionCatalysts\PayPal\Core\ConfirmOrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; @@ -126,8 +125,6 @@ public function doCreatePayPalOrder( $order instanceof EshopModelOrder ?? $order->setOrderNumber(); /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); - /** @var Logger $logger */ - $logger = oxNew(Logger::class); $request = $this->orderRequestFactory->getRequest( $basket, @@ -167,14 +164,14 @@ public function doCreatePayPalOrder( $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null, ); } catch (ApiException $exception) { - $logger->log( + $this->logger->log( 'error', 'Api error on order create call. ' . $exception->getErrorIssue(), [$exception] ); $this->handlePayPalApiError($exception); } catch (Exception $exception) { - $logger->log('error', 'Error on order create call.', [$exception]); + $this->logger->log('error', 'Error on order create call.', [$exception]); $this->setPaymentExecutionError(self::PAYMENT_ERROR_GENERIC); } @@ -242,9 +239,7 @@ public function doPatchPayPalOrder( Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (Exception $exception) { - /** @var Logger $logger */ - $logger = oxNew(Logger::class); - $logger->log('error', 'Error on order patch call.', [$exception]); + $this->logger->log('error', 'Error on order patch call.', [$exception]); throw $exception; } } @@ -270,8 +265,6 @@ public function doCapturePayPalOrder( $paymentService = Registry::get(ServiceFactory::class)->getPaymentService(); /** @var ApiOrderService $orderService */ $orderService = $this->serviceFactory->getOrderService(); - /** @var Logger $logger */ - $logger = oxNew(Logger::class); // Capture Order try { @@ -329,7 +322,7 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); - $logger->log('error', $exception->getMessage(), [$exception]); + $this->logger->log('error', $exception->getMessage(), [$exception]); throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } @@ -587,9 +580,7 @@ public function doExecuteUAPMPayment(EshopModelOrder $order, EshopModelBasket $b PayPalSession::unsetPayPalOrderId(); $this->removeTemporaryOrder(); //TODO: do we need to log this? - /** @var Logger $logger */ - $logger = oxNew(Logger::class); - $logger->log('error', $exception->getMessage(), [$exception]); + $this->logger->log('error', $exception->getMessage(), [$exception]); } //NOTE: payment not fully executed, we need customer interaction first @@ -713,14 +704,12 @@ public function doExecutePuiPayment( $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_PHONE); } catch (Exception $exception) { $this->setPaymentExecutionError(self::PAYMENT_ERROR_PUI_GENERIC); - /** @var Logger $logger */ - $logger = oxNew(Logger::class); - $logger->log('error', 'Error on pui order creation call.', [$exception]); + $this->logger->log('error', 'Error on pui order creation call.', [$exception]); } # TODO: check what we created, ensure it is a pui order # $paymentSource = $this->fetchOrderFields((string) $payPalOrderId, 'payment_source'); - # $logger->log('error', serialize($paymentSource)); + # $this->logger->log('error', serialize($paymentSource)); if (!$payPalOrderId) { return false; From 96597cb0a0c02d5558d9c35f36804c9b7dfe768a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 15 Dec 2023 17:15:19 +0100 Subject: [PATCH 016/265] fix codestyle --- src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php | 3 ++- src/Model/PaymentGateway.php | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index 41eb9674..ad1f1651 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -43,7 +43,8 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel } catch (ApiException $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); - $logger->log('debug', + $logger->log( + 'debug', 'Exception during PaymentCaptureCompletedHandler::getPayPalOrderDetails().', [$exception] ); diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index f295b547..9b1bd9fb 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -75,7 +75,7 @@ protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool $shopOrderId = (string)$order->getFieldData('oxordernr'); $paymentService->doPatchPayPalOrder($basket, $checkoutOrderId, $shopOrderId); } catch (Exception $exception) { - $logger->log('error','Error on order patch call.', [$exception]); + $logger->log('error', 'Error on order patch call.', [$exception]); } // Capture Order @@ -86,7 +86,7 @@ protected function doExecutePayPalExpressPayment(EshopModelOrder $order): bool // success means at this point, that we triggered the capture without errors $success = true; } catch (Exception $exception) { - $logger->log('error','Error on order capture call.', [$exception]); + $logger->log('error', 'Error on order capture call.', [$exception]); } // destroy PayPal-Session From 71df28785002af22748ab169d6396d0ded27d36b Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 2 Jan 2024 15:03:18 +0100 Subject: [PATCH 017/265] shorten 'OxidSolutionCatalysts\PayPal\Service\Logger' --- src/Controller/Admin/PayPalOrderController.php | 4 ++-- src/Core/Onboarding/Onboarding.php | 5 ++--- src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index fe5a15a0..d15bfc6f 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -96,7 +96,7 @@ public function executeFunction($functionName) $this->addTplParam('error', $exception->getErrorDescription()); /** @var Logger $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); + $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage()); } } @@ -159,7 +159,7 @@ public function render() } catch (ApiException $exception) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_ERROR_' . $exception->getErrorIssue())); /** @var Logger $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); + $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage()); } } elseif ( diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index 245a9936..86ea8895 100644 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -17,7 +17,6 @@ use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Onboarding as ApiOnboardingClient; -use Psr\Log\LoggerInterface; class Onboarding { @@ -63,7 +62,7 @@ public function fetchCredentials(): array $credentials = $apiClient->getCredentials(); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); + $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } @@ -158,7 +157,7 @@ public function fetchMerchantInformations(): array $merchantInformations = $apiClient->getMerchantInformations(); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); + $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); } return $merchantInformations; diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index ad1f1651..931dff65 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -42,7 +42,7 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel ->showOrderDetails($payPalOrderId, ''); } catch (ApiException $exception) { /** @var Logger $logger */ - $logger = $this->getServiceFromContainer('OxidSolutionCatalysts\PayPal\Service\Logger'); + $logger = $this->getServiceFromContainer(Logger::class); $logger->log( 'debug', 'Exception during PaymentCaptureCompletedHandler::getPayPalOrderDetails().', From 449c0acb1414de882734cc877e333bc820fe9fab Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 2 Jan 2024 15:03:39 +0100 Subject: [PATCH 018/265] use Logger instead of LoggerInterface --- src/Core/Events/Events.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index 89e4f740..1692e74f 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -10,7 +10,6 @@ namespace OxidSolutionCatalysts\PayPal\Core\Events; use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder; -use OxidEsales\Eshop\Application\Model\Payment as EshopModelPayment; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface; From 3782f9cb819657df20ee6bdf7726d9184209444f Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 5 Jan 2024 12:35:08 +0100 Subject: [PATCH 019/265] add missing class --- src/Core/Onboarding/Onboarding.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index 86ea8895..96aa3e90 100644 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -17,6 +17,7 @@ use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Onboarding as ApiOnboardingClient; +use Psr\Log\LoggerInterface; class Onboarding { From ec0245a898db1064f5a93bef90a2719b46c629d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 09:52:27 +0000 Subject: [PATCH 020/265] Bump actions/upload-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 59 +++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 3c663ec6..ff0b174d 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -150,7 +150,7 @@ jobs: - name: Upload log artifact if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: StylesLog-${{ matrix.php }} path: | @@ -196,13 +196,68 @@ jobs: - name: Upload log artifact if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: TestsLog-${{ matrix.php }} path: | source/coverage.xml source/phpunit.xml + codeception_tests: + strategy: + fail-fast: false + matrix: + php: [ '7.4', '8.0', '8.1' ] + group: + - 'oe_moduletemplate' + needs: [ install_shop_with_module ] + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3.3.2 + with: + path: | + ./* + key: moduleDevelopmentInstallation-${{ matrix.php }}-${{ github.sha }} + restore-keys: | + moduleDevelopmentInstallation-${{ matrix.php }}-${{ github.sha }} + + - name: Start containers + run: | + make up + sleep 2 + + - name: Install codeception dependencies + run: | + docker-compose exec -T php composer require codeception/module-rest:^1.4.2 --dev --no-update + docker-compose exec -T php composer require codeception/module-phpbrowser:^1.0.2 --dev --no-update + docker-compose exec -T php composer update + + - name: Run tests + run: | + docker-compose exec -T \ + -e PARTIAL_MODULE_PATHS=${{ env.MODULE_PATH }} \ + -e ACTIVATE_ALL_MODULES=1 \ + -e RUN_TESTS_FOR_SHOP=0 \ + -e RUN_TESTS_FOR_MODULES=0 \ + -e ADDITIONAL_TEST_PATHS='/var/www/vendor/${{ env.PACKAGE_NAME }}/tests' \ + php php vendor/bin/runtests-codeception + + - name: Stop containers + if: always() + run: | + docker-compose down + sleep 2 + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: CodeceptionTestsLog-${{ matrix.php }} + path: | + source/vendor/${{ env.PACKAGE_NAME }}/tests/Codeception/_output/ + source/source/log/oxideshop.log + source/data/php/logs/error_log.txt + sonarcloud: needs: [ styles, unit_tests ] if: always() From e24a0112adaec3dc10d28e111390a02c4cd676f3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 09:52:20 +0000 Subject: [PATCH 021/265] Bump actions/download-artifact from 3 to 4 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index ff0b174d..bdf6ab44 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -268,7 +268,7 @@ jobs: - name: Download phpunit artifacts continue-on-error: true - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: TestsLog-7.4 path: ./tests/ @@ -280,7 +280,7 @@ jobs: sed -i 's+/var/www/test-module/++' tests/phpunit.xml - name: Download styles artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: StylesLog-8.0 path: ./styles/ From 442f28929db93baca480b4e1e2f764f17221facf Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Thu, 21 Dec 2023 14:00:04 +0100 Subject: [PATCH 022/265] 688 Order number sent to PayPal transaction as custom value --- src/Controller/ProxyController.php | 1 - src/Model/PaymentGateway.php | 2 ++ src/Service/Payment.php | 8 +------- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 9ddb502b..800a6030 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -72,7 +72,6 @@ public function createOrder() null, '', '', - '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index 9b1bd9fb..5f6746e3 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -103,6 +103,8 @@ protected function doExecutePuiPayment(EshopModelOrder $order): bool $success = false; try { + //order number must be resolved before requesting payment + $order->setOrderNumber(); $success = $paymentService->doExecutePuiPayment( $order, Registry::getSession()->getBasket(), diff --git a/src/Service/Payment.php b/src/Service/Payment.php index 10c14554..2dcd1941 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -111,7 +111,6 @@ public function doCreatePayPalOrder( string $processingInstruction = null, string $paymentSource = null, string $payPalClientMetadataId = '', - string $payPalRequestId = '', string $payPalPartnerAttributionId = '', string $returnUrl = null, string $cancelUrl = null, @@ -159,9 +158,7 @@ public function doCreatePayPalOrder( $response = $orderService->createOrder( $request, $payPalPartnerAttributionId, - $payPalClientMetadataId, - 'return=minimal', - $order instanceof EshopModelOrder ? $order->getFieldData('oxordernr') : null, + $payPalClientMetadataId ); } catch (ApiException $exception) { $this->logger->log( @@ -192,7 +189,6 @@ public function doCreatePatchedOrder( null, null, '', - '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, @@ -611,7 +607,6 @@ public function doExecuteStandardPayment( null, null, '', - '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, $returnUrl, $cancelUrl, @@ -663,7 +658,6 @@ public function doCreateUAPMOrder(EshopModelBasket $basket): string null, null, '', - '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, From ff3b2c90eff02ee19010d4d48f206caf6375d029 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Tue, 2 Jan 2024 11:22:53 +0100 Subject: [PATCH 023/265] 688 CR fixes --- src/Core/OrderRequestFactory.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 7bc730af..dd2796ff 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -69,7 +69,7 @@ class OrderRequestFactory * @param Basket $basket * @param string $intent Order::INTENT_CAPTURE or Order::INTENT_AUTHORIZE constant values * @param null|string $userAction USER_ACTION_CONTINUE constant values - * @param null|string $transactionId transaction id + * @param null|string $customId custom id reference * @param null|string $processingInstruction processing instruction * @param null|string $paymentSource Payment-Source Name * @param null|string $invoiceId custom invoice number @@ -142,6 +142,8 @@ public function getRequest( $request->payer = $this->getPayer(); } + $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); + if ($userAction || $returnUrl || $cancelUrl) { $request->application_context = $this->getApplicationContext( $userAction, From ca2a9256f846938c7ed6295046998a4389cb288a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 5 Jan 2024 12:20:12 +0100 Subject: [PATCH 024/265] CHANGLOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c58068b..72f85aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - PayPal-Log consider Shop-ErrorLogLevel +## [2.3.4] - 2024-??-?? + +- Transfer OXID-Ordernumber to PayPal + ## [2.3.3] - 2023-11-16 - [0007549](https://bugs.oxid-esales.com/view.php?id=7549): Optional field in shop admin -> refund "Note to buyer" is transmitted to PayPal From 6723664705e964bee237104b4b8267b7e6453720 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:49:40 +0000 Subject: [PATCH 025/265] Bump docker/metadata-action from 5.3.0 to 5.4.0 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.3.0 to 5.4.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/31cebacef4805868f9ce9a0cb03ee36c32df2ac4...9dc751fe249ad99385a2583ee0d084c400eee04e) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index bdea7f41..5862c528 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -67,7 +67,7 @@ jobs: # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@31cebacef4805868f9ce9a0cb03ee36c32df2ac4 + uses: docker/metadata-action@9dc751fe249ad99385a2583ee0d084c400eee04e with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From 2f6bb3a4cbf37b220a6b54be0c49b9201cd4a08f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 09:11:50 +0000 Subject: [PATCH 026/265] Bump docker/metadata-action from 5.4.0 to 5.5.0 Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.4.0 to 5.5.0. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/9dc751fe249ad99385a2583ee0d084c400eee04e...dbef88086f6cef02e264edb7dbf63250c17cef6c) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 5862c528..2f11ee46 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -67,7 +67,7 @@ jobs: # https://github.com/docker/metadata-action - name: Extract Docker metadata id: meta - uses: docker/metadata-action@9dc751fe249ad99385a2583ee0d084c400eee04e + uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} From aabff6d0c0d9432e9492b3a08413cfef44739f52 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 11 Jan 2024 16:08:42 +0100 Subject: [PATCH 027/265] change CodeStyle --- migration/data/Version20231129135614.php | 6 +++--- src/Controller/OrderController.php | 10 +++++----- src/Controller/PayPalVaultingCardController.php | 2 +- src/Controller/PayPalVaultingController.php | 2 +- src/Controller/PaymentController.php | 6 +++--- src/Controller/VaultingTokenController.php | 8 ++++---- src/Core/Api/VaultingService.php | 2 +- src/Core/OrderRequestFactory.php | 10 +++++----- src/Core/ViewConfig.php | 4 ++-- src/Service/Payment.php | 3 ++- 10 files changed, 27 insertions(+), 26 deletions(-) diff --git a/migration/data/Version20231129135614.php b/migration/data/Version20231129135614.php index 96baebae..17c7afcf 100644 --- a/migration/data/Version20231129135614.php +++ b/migration/data/Version20231129135614.php @@ -12,17 +12,17 @@ */ final class Version20231129135614 extends AbstractMigration { - public function getDescription() : string + public function getDescription(): string { return ''; } - public function up(Schema $schema) : void + public function up(Schema $schema): void { $this->updateUserTable($schema); } - public function down(Schema $schema) : void + public function down(Schema $schema): void { } diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index cb44fcd6..317b8d39 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -85,7 +85,7 @@ public function render() if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid")) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId,$selectedVaultPaymentSourceIndex); + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId, $selectedVaultPaymentSourceIndex); //find out which payment token was selected by getting the index via request param $paymentType = key($selectedPaymentToken["payment_source"]); $paymentSource = $selectedPaymentToken["payment_source"][$paymentType]; @@ -93,13 +93,13 @@ public function render() $paymentDescription = ""; if ($paymentType == "card") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); - $paymentDescription = $paymentSource["brand"]." ".$string.$paymentSource["last_digits"]; - }elseif ($paymentType == "paypal") { + $paymentDescription = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; + } elseif ($paymentType === "paypal") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); - $paymentDescription = $string." ".$paymentSource["email_address"]; + $paymentDescription = $string . " " . $paymentSource["email_address"]; } - $this->addTplParam("vaultedPaymentDescription",$paymentDescription); + $this->addTplParam("vaultedPaymentDescription", $paymentDescription); } return parent::render(); diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php index 7238bab1..71454e0e 100644 --- a/src/Controller/PayPalVaultingCardController.php +++ b/src/Controller/PayPalVaultingCardController.php @@ -19,4 +19,4 @@ public function render() return parent::render(); } -} \ No newline at end of file +} diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php index fe8dc00d..d2d76f23 100644 --- a/src/Controller/PayPalVaultingController.php +++ b/src/Controller/PayPalVaultingController.php @@ -19,4 +19,4 @@ public function render() return parent::render(); } -} \ No newline at end of file +} diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 5f57ad95..8a9423f4 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -47,10 +47,10 @@ public function render() foreach ($vaultedPaymentTokens[0]["payment_source"] as $paymentSource) { if ($paymentType == "card") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); - $vaultedPaymentSources[$paymentType] = $paymentSource["brand"]." ".$string.$paymentSource["last_digits"]; - }elseif ($paymentType == "paypal") { + $vaultedPaymentSources[$paymentType] = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; + } elseif ($paymentType == "paypal") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); - $vaultedPaymentSources[$paymentType] = $string." ".$paymentSource["email_address"]; + $vaultedPaymentSources[$paymentType] = $string . " " . $paymentSource["email_address"]; } } $this->addTplParam("vaultedPaymentSources", $vaultedPaymentSources); diff --git a/src/Controller/VaultingTokenController.php b/src/Controller/VaultingTokenController.php index 68e7bb4b..b85b0393 100644 --- a/src/Controller/VaultingTokenController.php +++ b/src/Controller/VaultingTokenController.php @@ -33,9 +33,9 @@ public function generatePaymentToken() $setupToken = Registry::getRequest()->getRequestParameter("token"); $paymentToken = $vaultingService->createVaultPaymentToken($setupToken); - if($this->storePayPalUserId($paymentToken["customer"]["id"])) { + if ($this->storePayPalUserId($paymentToken["customer"]["id"])) { $this->outputJson(["state" => "SUCCESS"]); - }else { + } else { $this->outputJson(["state" => "ERROR"]); } } @@ -49,7 +49,7 @@ public function generateAccessTokenFromCustomerId($payPalCustomerId) protected function getVaultingService() { - if(!$this->vaultingService) { + if (!$this->vaultingService) { $this->vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); } @@ -91,4 +91,4 @@ protected function outputJson($response) $utils->setHeader('Content-Type: application/json; charset=utf-8'); $utils->showMessageAndExit(json_encode($response)); } -} \ No newline at end of file +} diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index c6ecd97e..6c9e48f1 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -201,7 +201,7 @@ public function getVaultPaymentTokens($paypalCustomerId) return null; } - $path = '/v3/vault/payment-tokens?customer_id='.$paypalCustomerId; + $path = '/v3/vault/payment-tokens?customer_id=' . $paypalCustomerId; $method = 'get'; $response = $this->send($method, $path); diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index dd2796ff..aa181cc7 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -46,6 +46,7 @@ class OrderRequestFactory { use ServiceContainer; + /** * After you redirect the customer to the PayPal payment page, a Continue button appears. * Use this option when the final amount is not known when the checkout flow is initiated and you want to @@ -104,17 +105,17 @@ public function getRequest( $request->purchase_units = $this->getPurchaseUnits($transactionId, $invoiceId, $withArticles); $useVaultedPayment = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); - if($useVaultedPayment) { + if ($useVaultedPayment) { $config = Registry::getConfig(); $vaultingService = $this->getVaultingService(); $payPalCustomerId = $this->getUsersPayPalCustomerId(); - $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId,$selectedVaultPaymentSourceIndex); + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId, $selectedVaultPaymentSourceIndex); //find out which payment token was selected by getting the index via request param $paymentType = key($selectedPaymentToken["payment_source"]); $useCard = $paymentType == "card"; - $this->modifyPaymentSourceForVaulting($request,$useCard); + $this->modifyPaymentSourceForVaulting($request, $useCard); //we use the PayPal payment type as a "dummy payment" when we use vaulted payments. //therefore, we need to use a returnURL depending on the payment type. @@ -129,7 +130,7 @@ public function getRequest( false ); return $request; - }elseif (Registry::getRequest()->getRequestParameter("vaultPayment")) { + } elseif (Registry::getRequest()->getRequestParameter("vaultPayment")) { $paymentType = Registry::getRequest()->getRequestParameter("oscPayPalPaymentTypeForVaulting"); $card = $paymentType == PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; @@ -620,7 +621,6 @@ protected function modifyPaymentSourceForVaulting(OrderRequest $request, $useCar //use selected vault if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $this->getUsersPayPalCustomerId()) { - $paymentTokens = $vaultingService->getVaultPaymentTokens($payPalCustomerId); //find out which payment token was selected by getting the index via request param $selectedPaymentToken = $paymentTokens["payment_tokens"][$selectedVaultPaymentSourceIndex]; diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 2b1c9930..bcfac86a 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -94,7 +94,7 @@ public function isPayPalExpressPaymentEnabled(): bool return $this->getServiceFromContainer(ModuleSettings::class)->isPayPalCheckoutExpressPaymentEnabled(); } - public function getIsVaultingActive():bool + public function getIsVaultingActive(): bool { return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); } @@ -248,7 +248,7 @@ protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): str $params['components'] .= ',messages'; } - if($this->getIsVaultingActive()) { + if ($this->getIsVaultingActive()) { $params['components'] .= ',card-fields'; } diff --git a/src/Service/Payment.php b/src/Service/Payment.php index 2dcd1941..cc158bbd 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -44,6 +44,7 @@ class Payment { use ServiceContainer; + public const PAYMENT_ERROR_NONE = 'PAYPAL_PAYMENT_ERROR_NONE'; public const PAYMENT_ERROR_GENERIC = 'PAYPAL_PAYMENT_ERROR_GENERIC'; public const PAYMENT_ERROR_PUI_PHONE = 'PAYPAL_PAYMENT_ERROR_PUI_PHONE'; @@ -636,7 +637,7 @@ public function doExecuteStandardPayment( //no customer interaction needed if a vaulted payment is used if ($response->status === Constants::PAYPAL_STATUS_COMPLETED) { - return $returnUrl."&vaulting=true"; + return $returnUrl . "&vaulting=true"; } if (!$redirectLink) { From 9fe835f1bd03019693f5f7a534da42294772db1a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 11 Jan 2024 16:33:00 +0100 Subject: [PATCH 028/265] change CodeStyle --- src/Controller/OrderController.php | 14 +++++++++++--- src/Controller/PayPalVaultingCardController.php | 4 ++++ src/Controller/PayPalVaultingController.php | 4 ++++ src/Controller/PaymentController.php | 3 ++- src/Core/OrderRequestFactory.php | 11 ++++++++--- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 317b8d39..104f4316 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -82,10 +82,16 @@ public function render() $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); $config = Registry::getConfig(); - if (!is_null($selectedVaultPaymentSourceIndex) && $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid")) { + if ( + !is_null($selectedVaultPaymentSourceIndex) && + $payPalCustomerId = $config->getUser()->getFieldData("oscpaypalcustomerid") + ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId, $selectedVaultPaymentSourceIndex); + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex( + $payPalCustomerId, + $selectedVaultPaymentSourceIndex + ); //find out which payment token was selected by getting the index via request param $paymentType = key($selectedPaymentToken["payment_source"]); $paymentSource = $selectedPaymentToken["payment_source"][$paymentType]; @@ -284,7 +290,9 @@ public function finalizepaypalsession(): string $sessionCheckoutOrderId = PayPalSession::getCheckoutOrderId(); $vaulting = Registry::getRequest()->getRequestParameter("vaulting"); - $cancelSession = !$sessionOrderId || !$sessionCheckoutOrderId || ($standardRequestId !== $sessionCheckoutOrderId); + $cancelSession = !$sessionOrderId || + !$sessionCheckoutOrderId || + ($standardRequestId !== $sessionCheckoutOrderId); if (!$vaulting && $cancelSession) { $this->cancelpaypalsession('request to session mismatch'); } diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php index 71454e0e..9e693b44 100644 --- a/src/Controller/PayPalVaultingCardController.php +++ b/src/Controller/PayPalVaultingCardController.php @@ -11,6 +11,10 @@ */ class PayPalVaultingCardController extends AccountController { + /** + * @var string Current class template name. + */ + // phpcs:ignore PSR2.Classes.PropertyDeclaration protected $_sThisTemplate = 'modules/osc/paypal/account_vaulting_card.tpl'; public function render() diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php index d2d76f23..bd725a70 100644 --- a/src/Controller/PayPalVaultingController.php +++ b/src/Controller/PayPalVaultingController.php @@ -11,6 +11,10 @@ */ class PayPalVaultingController extends AccountController { + /** + * @var string Current class template name. + */ + // phpcs:ignore PSR2.Classes.PropertyDeclaration protected $_sThisTemplate = 'modules/osc/paypal/account_vaulting_paypal.tpl'; public function render() diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 8a9423f4..32ee6db8 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -47,7 +47,8 @@ public function render() foreach ($vaultedPaymentTokens[0]["payment_source"] as $paymentSource) { if ($paymentType == "card") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); - $vaultedPaymentSources[$paymentType] = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; + $vaultedPaymentSources[$paymentType] = $paymentSource["brand"] . " " . + $string . $paymentSource["last_digits"]; } elseif ($paymentType == "paypal") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); $vaultedPaymentSources[$paymentType] = $string . " " . $paymentSource["email_address"]; diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index aa181cc7..8939ba9c 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -110,7 +110,10 @@ public function getRequest( $vaultingService = $this->getVaultingService(); $payPalCustomerId = $this->getUsersPayPalCustomerId(); - $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex($payPalCustomerId, $selectedVaultPaymentSourceIndex); + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex( + $payPalCustomerId, + $selectedVaultPaymentSourceIndex + ); //find out which payment token was selected by getting the index via request param $paymentType = key($selectedPaymentToken["payment_source"]); $useCard = $paymentType == "card"; @@ -655,8 +658,10 @@ protected function modifyPaymentSourceForVaulting(OrderRequest $request, $useCar ], "experience_context" => [ - "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', - "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', + "return_url" => $config->getSslShopUrl() . + 'index.php?cl=order&fnc=finalizepaypalsession', + "cancel_url" => $config->getSslShopUrl() . + 'index.php?cl=order&fnc=cancelpaypalsession', "shipping_preference" => "SET_PROVIDED_ADDRESS", ] ], From 45362073f47111fb8d9058e0b69c45ddae33ba3e Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Fri, 12 Jan 2024 18:14:32 +0100 Subject: [PATCH 029/265] PSPAYPAL-680 - fix viewconfig throwing error for non logged in users --- src/Core/OrderRequestFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 8939ba9c..90473a0c 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -135,7 +135,7 @@ public function getRequest( return $request; } elseif (Registry::getRequest()->getRequestParameter("vaultPayment")) { $paymentType = Registry::getRequest()->getRequestParameter("oscPayPalPaymentTypeForVaulting"); - $card = $paymentType == PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; + $card = ($paymentType == PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID); $this->modifyPaymentSourceForVaulting($request, $card); From 76780227e6f05b2168c5dc23c64051ed13ac46aa Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 18 Jan 2024 17:18:47 +0100 Subject: [PATCH 030/265] PSPAYPAL-680 - add eligibility check for vaulting --- metadata.php | 0 src/Core/Config.php | 5 +++++ src/Core/Onboarding/Onboarding.php | 24 +++++++++++++++++++++++- src/Service/ModuleSettings.php | 16 ++++++++++++++++ views/de/admin_translations.php | 2 ++ views/en/admin_translations.php | 2 ++ views/smarty/admin/oscpaypalconfig.tpl | 0 7 files changed, 48 insertions(+), 1 deletion(-) mode change 100644 => 100755 metadata.php mode change 100644 => 100755 src/Core/Config.php mode change 100644 => 100755 src/Core/Onboarding/Onboarding.php mode change 100644 => 100755 src/Service/ModuleSettings.php mode change 100644 => 100755 views/de/admin_translations.php mode change 100644 => 100755 views/en/admin_translations.php mode change 100644 => 100755 views/smarty/admin/oscpaypalconfig.tpl diff --git a/metadata.php b/metadata.php old mode 100644 new mode 100755 diff --git a/src/Core/Config.php b/src/Core/Config.php old mode 100644 new mode 100755 index 29817e64..330a9f6a --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -109,6 +109,11 @@ public function isPuiEligibility(): bool return $this->getServiceFromContainer(ModuleSettings::class)->isPuiEligibility(); } + public function isVaultingEligibility(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isVaultingEligibility(); + } + public function isLiveAcdcEligibility(): bool { return $this->getServiceFromContainer(ModuleSettings::class)->isLiveAcdcEligibility(); diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php old mode 100644 new mode 100755 index 96aa3e90..3fe64e28 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -172,6 +172,18 @@ public function saveEligibility(array $merchantInformations): array $isPuiEligibility = false; $isAcdcEligibility = false; + $isVaultingEligibility = false; + $isVaultingCapability = false; + + foreach ($merchantInformations['capabilities'] as $capability) { + if ( + $capability['name'] === 'PAYPAL_WALLET_VAULTING_ADVANCED' && + $capability['status'] === 'ACTIVE' + ) { + $isVaultingCapability = true; + break; + } + } foreach ($merchantInformations['products'] as $product) { if ( @@ -185,15 +197,25 @@ public function saveEligibility(array $merchantInformations): array ) { $isAcdcEligibility = true; } + + if ( + $product['name'] === 'PPCP_CUSTOM' && + in_array('PAYPAL_WALLET_VAULTING_ADVANCED', $product['capabilities']) && + $isVaultingCapability + ) { + $isVaultingEligibility = true; + } } $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $moduleSettings->savePuiEligibility($isPuiEligibility); $moduleSettings->saveAcdcEligibility($isAcdcEligibility); + $moduleSettings->saveVaultingEligibility($isVaultingEligibility); return [ 'acdc' => $isAcdcEligibility, - 'pui' => $isPuiEligibility + 'pui' => $isPuiEligibility, + 'vaulting' => $isVaultingEligibility, ]; } } diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php old mode 100644 new mode 100755 index 499741bc..69c25e1f --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -158,6 +158,13 @@ public function isPuiEligibility(): bool $this->isLivePuiEligibility(); } + public function isVaultingEligibility(): bool + { + return $this->isSandbox()? + $this->isSandBoxVaultingEligibility() : + $this->isLiveVaultingEligibility(); + } + public function getLiveClientId(): string { return (string)$this->getSettingValue('oscPayPalClientId'); @@ -448,6 +455,15 @@ public function savePuiEligibility(bool $eligibility): void } } + public function saveVaultingEligibility(bool $eligibility): void + { + if ($this->isSandbox()) { + $this->save('oscPayPalSandboxVaultingEligibility', $eligibility); + } else { + $this->save('oscPayPalVaultingEligibility', $eligibility); + } + } + public function saveWebhookId(string $webhookId): void { if ($this->isSandbox()) { diff --git a/views/de/admin_translations.php b/views/de/admin_translations.php old mode 100644 new mode 100755 index 5d3fe648..2977be51 --- a/views/de/admin_translations.php +++ b/views/de/admin_translations.php @@ -71,6 +71,8 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK' => '(Alternativ zur fehlenden Zahlart wird ein zusätzlicher Button "Kreditkarte" unter den Paypal-Buttons angezeigt.)', 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_LOCALISATIONS' => 'Spracheinstellungen', 'OSC_PAYPAL_LOCALES' => 'regionale Spracheinstellungen', 'HELP_OSC_PAYPAL_LOCALES' => 'PayPal unterstützt die Anzeige der PayPal-Buttons in regionalen Sprachen. Bitte hinterlegen sie die Codes kommasepariert im ISO 639-1 alpha-2 / ISO 3166-1 alpha-2 - Format (z.B. de_DE). Der erste Eintrag ist der Standard-Eintrag.', diff --git a/views/en/admin_translations.php b/views/en/admin_translations.php old mode 100644 new mode 100755 index 0322f804..35821f8d --- a/views/en/admin_translations.php +++ b/views/en/admin_translations.php @@ -70,6 +70,8 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK' => '(As an alternative to the missing payment method, an additional "credit card" button is displayed under the Paypal buttons.)', 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_LOCALISATIONS' => 'Locals', 'OSC_PAYPAL_LOCALES' => 'regional language settings', 'HELP_OSC_PAYPAL_LOCALES' => 'PayPal supports displaying the PayPal buttons in regional languages. Please enter the codes separated by commas in ISO 639-1 alpha-2 / ISO 3166-1 alpha-2 format (e.g. de_DE). The first entry is the default entry.', diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl old mode 100644 new mode 100755 From 496262e0e1fbeea4e3cae7f813d73b6f69da0407 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Fri, 19 Jan 2024 15:09:48 +0100 Subject: [PATCH 031/265] PSPAYPAL-680 - move checkbox into payment card field --- .../checkout_order_btn_submit_bottom.tpl | 3 +- .../page/checkout/shipping_and_payment.tpl | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index e168318a..0ebde48a 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -1,9 +1,8 @@ [{assign var="payment" value=$oView->getPayment()}] [{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal" == $payment->getId()}]
- + -
[{/if}] [{if "oscpaypal_pui" == $payment->getId()}] diff --git a/views/blocks/page/checkout/shipping_and_payment.tpl b/views/blocks/page/checkout/shipping_and_payment.tpl index e972cc8e..e06cadc1 100644 --- a/views/blocks/page/checkout/shipping_and_payment.tpl +++ b/views/blocks/page/checkout/shipping_and_payment.tpl @@ -1,4 +1,33 @@ [{assign var="payment" value=$oView->getPayment()}] +[{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal" == $payment->getId()}] + + + +[{/if}] + [{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal_pui" == $payment->getId() || $vaultedPaymentDescription}] [{if $oViewConf->isFlowCompatibleTheme()}] [{include file="modules/osc/paypal/shipping_and_payment_flow.tpl"}] From e69b7daaf601433c2a9b2169f547265cbe3d31f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:32:36 +0000 Subject: [PATCH 032/265] Bump actions/cache from 3.3.2 to 3.3.3 Bumps [actions/cache](https://github.com/actions/cache) from 3.3.2 to 3.3.3. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.2...v3.3.3) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index bdf6ab44..1a8f7deb 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -24,7 +24,7 @@ jobs: run: git clone --depth 1 https://github.com/OXID-eSales/oxideshop_ce.git --branch b-7.0.x --single-branch source - name: Cache current installation - uses: actions/cache@v3.3.2 + uses: actions/cache@v3.3.3 with: path: | ./* @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v3.3.3 with: path: | ./* @@ -214,7 +214,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v3.3.2 + uses: actions/cache@v3.3.3 with: path: | ./* From e613b00d8cdda2cc66a80deb021d5f42060c9734 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 09:34:02 +0000 Subject: [PATCH 033/265] Bump actions/cache from 3.3.3 to 4.0.0 Bumps [actions/cache](https://github.com/actions/cache) from 3.3.3 to 4.0.0. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3.3.3...v4.0.0) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 1a8f7deb..00435dec 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -24,7 +24,7 @@ jobs: run: git clone --depth 1 https://github.com/OXID-eSales/oxideshop_ce.git --branch b-7.0.x --single-branch source - name: Cache current installation - uses: actions/cache@v3.3.3 + uses: actions/cache@v4.0.0 with: path: | ./* @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v3.3.3 + uses: actions/cache@v4.0.0 with: path: | ./* @@ -214,7 +214,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v3.3.3 + uses: actions/cache@v4.0.0 with: path: | ./* From d6fd685c7fa4838f9ade063eed94da736bdc919c Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 26 Jan 2024 11:08:29 +0100 Subject: [PATCH 034/265] Release v2.3.4 --- CHANGELOG.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72f85aa4..4bf567aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,13 +59,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support -## [2.3.4] - 2023-??-?? - -- PayPal-Log consider Shop-ErrorLogLevel - -## [2.3.4] - 2024-??-?? +## [2.3.4] - 2024-01-26 - Transfer OXID-Ordernumber to PayPal +- PayPal-Log consider Shop-ErrorLogLevel +- Composer-Installation now via packagist. + - https://packagist.org/packages/oxid-solution-catalysts/paypal-module + - https://packagist.org/packages/oxid-solution-catalysts/paypal-client +- "Repositories"-requirement for Source https://paypal-module.packages.oxid-esales.com/ not need anymore ## [2.3.3] - 2023-11-16 From df466ab991a3e187588f393b01c41dc54f786f3b Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Mon, 5 Feb 2024 17:29:10 +0100 Subject: [PATCH 035/265] PSPAYPAL-680 - refactor user opt-in for vaulting checkbox --- metadata.php | 2 + src/Core/OrderRequestFactory.php | 2 +- .../checkout_order_btn_submit_bottom.tpl | 3 +- .../page/checkout/shipping_and_payment.tpl | 34 ++-------- views/smarty/frontend/acdc.tpl | 5 ++ .../checkout/shipping_and_payment_paypal.tpl | 67 +++++++++++++++++++ .../checkout/shipping_and_payment_paypal.tpl | 67 +++++++++++++++++++ 7 files changed, 149 insertions(+), 31 deletions(-) create mode 100644 views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl create mode 100644 views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl diff --git a/metadata.php b/metadata.php index 70b655dc..73a18b3b 100755 --- a/metadata.php +++ b/metadata.php @@ -122,6 +122,8 @@ 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', + 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', + 'modules/osc/paypal/shipping_and_payment_paypal_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl', 'modules/osc/paypal/checkout_order_btn_submit_bottom_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/checkout_order_btn_submit_bottom.tpl', 'modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/checkout_order_btn_submit_bottom.tpl', diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 90473a0c..e0052015 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -133,7 +133,7 @@ public function getRequest( false ); return $request; - } elseif (Registry::getRequest()->getRequestParameter("vaultPayment")) { + } elseif (Registry::getRequest()->getRequestParameter("vaultPayment") === "true") { $paymentType = Registry::getRequest()->getRequestParameter("oscPayPalPaymentTypeForVaulting"); $card = ($paymentType == PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID); diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index 0ebde48a..8bd58774 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -1,8 +1,7 @@ [{assign var="payment" value=$oView->getPayment()}] -[{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal" == $payment->getId()}] +[{if "oscpaypal" == $payment->getId()}]
-
[{/if}] [{if "oscpaypal_pui" == $payment->getId()}] diff --git a/views/blocks/page/checkout/shipping_and_payment.tpl b/views/blocks/page/checkout/shipping_and_payment.tpl index e06cadc1..c47ae68f 100644 --- a/views/blocks/page/checkout/shipping_and_payment.tpl +++ b/views/blocks/page/checkout/shipping_and_payment.tpl @@ -1,32 +1,4 @@ [{assign var="payment" value=$oView->getPayment()}] -[{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal" == $payment->getId()}] - - - -[{/if}] [{if "oscpaypal_acdc" == $payment->getId() || "oscpaypal_pui" == $payment->getId() || $vaultedPaymentDescription}] [{if $oViewConf->isFlowCompatibleTheme()}] @@ -34,6 +6,12 @@ [{else}] [{include file="modules/osc/paypal/shipping_and_payment_wave.tpl"}] [{/if}] +[{elseif "oscpaypal" == $payment->getId()}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/shipping_and_payment_paypal_flow.tpl"}] + [{else}] + [{include file="modules/osc/paypal/shipping_and_payment_paypal_wave.tpl"}] + [{/if}] [{else}] [{$smarty.block.parent}] [{/if}] \ No newline at end of file diff --git a/views/smarty/frontend/acdc.tpl b/views/smarty/frontend/acdc.tpl index 7a626c20..438b19d1 100644 --- a/views/smarty/frontend/acdc.tpl +++ b/views/smarty/frontend/acdc.tpl @@ -19,6 +19,8 @@ + + - -[{/if}] [{if $oViewConf->isFlowCompatibleTheme()}] [{include file='modules/osc/paypal/change_payment_flow.tpl'}] [{else}] diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index 8bd58774..e13202da 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -1,8 +1,6 @@ [{assign var="payment" value=$oView->getPayment()}] [{if "oscpaypal" == $payment->getId()}] -
- -
+ [{/if}] [{if "oscpaypal_pui" == $payment->getId()}] [{if $oViewConf->isFlowCompatibleTheme()}] diff --git a/views/smarty/frontend/blocks/page/checkout/payment__change_payment.tpl b/views/smarty/frontend/blocks/page/checkout/payment__change_payment.tpl index 6c63b5e0..f12d44ec 100644 --- a/views/smarty/frontend/blocks/page/checkout/payment__change_payment.tpl +++ b/views/smarty/frontend/blocks/page/checkout/payment__change_payment.tpl @@ -1,3 +1,55 @@ +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+ [{assign var="iterator" value=0}] + [{foreach from=$vaultedPaymentSources item=vaultedPayment key="paymentType"}] + [{foreach from=$vaultedPayment item=paymentDescription name="paymentSources"}] +
+
+
+ + +
+
+
+ [{math assign="iterator" equation="x+1" x=$iterator}] + [{/foreach}] + [{/foreach}] + +
+ +
+
+
+ + +[{/if}] [{if 'oscpaypal_express'|array_key_exists:$oView->getPaymentList() && $oViewConf->isPayPalExpressSessionActive()}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}]
diff --git a/views/tpl/flow/page/checkout/change_payment.tpl b/views/tpl/flow/page/checkout/change_payment.tpl new file mode 100644 index 00000000..cdba60df --- /dev/null +++ b/views/tpl/flow/page/checkout/change_payment.tpl @@ -0,0 +1,79 @@ +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+ [{assign var="iterator" value=0}] + [{foreach from=$vaultedPaymentSources item=vaultedPayment key="paymentType"}] + [{foreach from=$vaultedPayment item=paymentDescription name="paymentSources"}] +
+
+
+ + +
+
+
+ [{math assign="iterator" equation="x+1" x=$iterator}] + [{/foreach}] + [{/foreach}] + +
+ +
+
+
+ + +[{/if}] + +[{if 'oscpaypal_express'|array_key_exists:$oView->getPaymentList() && $oViewConf->isPayPalExpressSessionActive()}] + [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] +
+
+
+

[{oxmultilang ident="OSC_PAYPAL_PAY_EXPRESS"}]

+
+
+
+ [{oxmultilang ident="OSC_PAYPAL_PAY_PROCESSED"}] +
+ + [{capture name="hide_payment"}] + [{literal}] + $(function () { + $('#payment > .panel.panel-default:first').hide(); + }); + [{/literal}] + [{/capture}] + [{oxscript add=$smarty.capture.hide_payment}] +
+
+
+[{/if}] From a11daa38ac11b97246f1125e5df33fe7e368ae06 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 29 Feb 2024 16:21:20 +0100 Subject: [PATCH 061/265] PSPAYPAL-680 - add delete token functionality --- metadata.php | 11 ++++++ .../PayPalVaultingCardController.php | 14 +++++++ src/Controller/PayPalVaultingController.php | 15 ++++++++ translations/de/oscpaypal_de_lang.php | 2 + translations/en/oscpaypal_en_lang.php | 3 +- .../frontend/blocks/vaultedpaymentsources.tpl | 26 ++----------- .../flow/vaulting/vaultedpaymentsources.tpl | 38 +++++++++++++++++++ .../wave/vaulting/vaultedpaymentsources.tpl | 38 +++++++++++++++++++ 8 files changed, 124 insertions(+), 23 deletions(-) create mode 100644 views/tpl/flow/vaulting/vaultedpaymentsources.tpl create mode 100644 views/tpl/wave/vaulting/vaultedpaymentsources.tpl diff --git a/metadata.php b/metadata.php index ee104e4d..322ae66b 100755 --- a/metadata.php +++ b/metadata.php @@ -146,6 +146,17 @@ // PSPAYPAL-491 Installment banners 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', + + //PSPAYPAL-680 Vaulting + 'modules/osc/paypal/account_vaulting_paypal.tpl' => 'osc/paypal/views/tpl/shared/page/account/account_vaulting_paypal.tpl', + 'modules/osc/paypal/account_vaulting_card.tpl' => 'osc/paypal/views/tpl/shared/page/account/account_vaulting_card.tpl', + 'modules/osc/paypal/vaultedpaymentsources.tpl' => 'osc/paypal/views/tpl/shared/vaultedpaymentsources.tpl', + 'modules/osc/paypal/vaultedpaymentsources_flow.tpl' => 'osc/paypal/views/tpl/flow/vaulting/vaultedpaymentsources.tpl', + 'modules/osc/paypal/vaultedpaymentsources_wave.tpl' => 'osc/paypal/views/tpl/wave/vaulting/vaultedpaymentsources.tpl', + ], + 'events' => [ + 'onActivate' => '\OxidSolutionCatalysts\PayPal\Core\Events\Events::onActivate', + 'onDeactivate' => '\OxidSolutionCatalysts\PayPal\Core\Events\Events::onDeactivate' ], 'blocks' => [ [ diff --git a/src/Controller/PayPalVaultingCardController.php b/src/Controller/PayPalVaultingCardController.php index 9e693b44..7e44030b 100644 --- a/src/Controller/PayPalVaultingCardController.php +++ b/src/Controller/PayPalVaultingCardController.php @@ -23,4 +23,18 @@ public function render() return parent::render(); } + + public function deleteVaultedPayment() + { + $paymentTokenId = Registry::getRequest()->getRequestEscapedParameter("paymentTokenId"); + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + + if (!$vaultingService->deleteVaultedPayment($paymentTokenId)) { + Registry::getUtilsView()->addErrorToDisplay( + Registry::getLang()->translateString('OSC_PAYPAL_DELETE_FAILED'), + false, + true + ); + } + } } diff --git a/src/Controller/PayPalVaultingController.php b/src/Controller/PayPalVaultingController.php index bd725a70..7c5c3d1c 100644 --- a/src/Controller/PayPalVaultingController.php +++ b/src/Controller/PayPalVaultingController.php @@ -2,6 +2,7 @@ namespace OxidSolutionCatalysts\PayPal\Controller; +use mysql_xdevapi\Exception; use OxidEsales\Eshop\Application\Controller\AccountController; use OxidEsales\Eshop\Core\Registry; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; @@ -23,4 +24,18 @@ public function render() return parent::render(); } + + public function deleteVaultedPayment() + { + $paymentTokenId = Registry::getRequest()->getRequestEscapedParameter("paymentTokenId"); + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + + if (!$vaultingService->deleteVaultedPayment($paymentTokenId)) { + Registry::getUtilsView()->addErrorToDisplay( + Registry::getLang()->translateString('OSC_PAYPAL_DELETE_FAILED'), + false, + true + ); + } + } } diff --git a/translations/de/oscpaypal_de_lang.php b/translations/de/oscpaypal_de_lang.php index 35ee9151..351665b9 100644 --- a/translations/de/oscpaypal_de_lang.php +++ b/translations/de/oscpaypal_de_lang.php @@ -56,7 +56,9 @@ 'OSC_PAYPAL_VAULTING_ERROR' => 'Beim Speichern Ihrer Zahlart ist etwas schiefgelaufen.', 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Ihre Zahlart wurde erfolgreich gespeichert. Sie finden Ihre gespeicherten Zahlungsarten im "Mein Konto" Bereich.', 'OSC_PAYPAL_VAULTING_SAVE' => 'Zahlart speichern', + 'OSC_PAYPAL_VAULTING_DELETE' => 'Zahlart löschen', 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Weiter mit gespeicherter Zahlungsart', 'OSC_PAYPAL_CARD_ENDING_IN' => 'endet mit ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal Zahlung mit', + 'OSC_PAYPAL_DELETE_FAILED' => 'Beim Löschen Ihrer Zahlart ist etwas schiefgelaufen.', ]; diff --git a/translations/en/oscpaypal_en_lang.php b/translations/en/oscpaypal_en_lang.php index 2efb229a..672ef7e7 100644 --- a/translations/en/oscpaypal_en_lang.php +++ b/translations/en/oscpaypal_en_lang.php @@ -54,8 +54,9 @@ 'OSC_PAYPAL_VAULTING_ERROR' => 'There was an error saving your payment method.', 'OSC_PAYPAL_VAULTING_SUCCESS' => 'Your payment method was saved successfully. You will find your saved payments in your Account area.', 'OSC_PAYPAL_VAULTING_SAVE' => 'Save payment', + 'OSC_PAYPAL_VAULTING_DELETE' => 'Delete payment', 'OSC_PAYPAL_CONTINUE_TO_NEXT_STEP' => 'Continue with saved payment method', 'OSC_PAYPAL_CARD_ENDING_IN' => 'ending in ●●●', 'OSC_PAYPAL_CARD_PAYPAL_PAYMENT' => 'PayPal payment with', - + 'OSC_PAYPAL_DELETE_FAILED' => 'There was an error deleting your payment method.' ]; diff --git a/views/smarty/frontend/blocks/vaultedpaymentsources.tpl b/views/smarty/frontend/blocks/vaultedpaymentsources.tpl index 09df17a4..4628f45b 100644 --- a/views/smarty/frontend/blocks/vaultedpaymentsources.tpl +++ b/views/smarty/frontend/blocks/vaultedpaymentsources.tpl @@ -1,23 +1,5 @@ -[{assign var="vaultedPaymentSources" value=$oViewConf->getVaultPaymentTokens()}] - -[{if $vaultedPaymentSources}] -
-
-

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

-
-
-
    - [{foreach from=$vaultedPaymentSources item=paymentToken}] - [{if $paymentToken.payment_source.card}] - [{assign var="brand" value=$paymentToken.payment_source.card.brand}] - [{assign var="lastdigits" value=$paymentToken.payment_source.card.last_digits}] -
  • [{$brand}] [{oxmultilang ident="OSC_PAYPAL_CARD_ENDING_IN"}][{$lastdigits}]
  • - [{elseif $paymentToken.payment_source.paypal}] - [{assign var="lastdigits" value=$paymentToken.payment_source.paypal.email_address}] -
  • [{oxmultilang ident="OSC_PAYPAL_CARD_PAYPAL_PAYMENT"}] [{$lastdigits}]
  • - [{/if}] - [{/foreach}] -
-
-
+[{if $oViewConf->isFlowCompatibleTheme()}] + [{include file='modules/osc/paypal/vaultedpaymentsources_flow.tpl'}] +[{else}] + [{include file='modules/osc/paypal/vaultedpaymentsources_wave.tpl'}] [{/if}] \ No newline at end of file diff --git a/views/tpl/flow/vaulting/vaultedpaymentsources.tpl b/views/tpl/flow/vaulting/vaultedpaymentsources.tpl new file mode 100644 index 00000000..88a0e292 --- /dev/null +++ b/views/tpl/flow/vaulting/vaultedpaymentsources.tpl @@ -0,0 +1,38 @@ +[{assign var="vaultedPaymentSources" value=$oViewConf->getVaultPaymentTokens()}] + +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+
    + [{foreach from=$vaultedPaymentSources item=paymentToken}] +
  • +
    + + + [{if $paymentToken.payment_source.card}] + [{assign var="brand" value=$paymentToken.payment_source.card.brand}] + [{assign var="lastdigits" value=$paymentToken.payment_source.card.last_digits}] + [{$brand}] [{oxmultilang ident="OSC_PAYPAL_CARD_ENDING_IN"}][{$lastdigits}] + [{elseif $paymentToken.payment_source.paypal}] + [{assign var="lastdigits" value=$paymentToken.payment_source.paypal.email_address}] + [{oxmultilang ident="OSC_PAYPAL_CARD_PAYPAL_PAYMENT"}] [{$lastdigits}] + [{/if}] + + +
    +
  • + [{/foreach}] +
+
+
+[{/if}] diff --git a/views/tpl/wave/vaulting/vaultedpaymentsources.tpl b/views/tpl/wave/vaulting/vaultedpaymentsources.tpl new file mode 100644 index 00000000..11289d9b --- /dev/null +++ b/views/tpl/wave/vaulting/vaultedpaymentsources.tpl @@ -0,0 +1,38 @@ +[{assign var="vaultedPaymentSources" value=$oViewConf->getVaultPaymentTokens()}] + +[{if $vaultedPaymentSources}] +
+
+

[{oxmultilang ident="OSC_PAYPAL_VAULTING_VAULTED_PAYMENTS"}]

+
+
+
    + [{foreach from=$vaultedPaymentSources item=paymentToken}] +
  • +
    + + + [{if $paymentToken.payment_source.card}] + [{assign var="brand" value=$paymentToken.payment_source.card.brand}] + [{assign var="lastdigits" value=$paymentToken.payment_source.card.last_digits}] + [{$brand}] [{oxmultilang ident="OSC_PAYPAL_CARD_ENDING_IN"}][{$lastdigits}] + [{elseif $paymentToken.payment_source.paypal}] + [{assign var="lastdigits" value=$paymentToken.payment_source.paypal.email_address}] + [{oxmultilang ident="OSC_PAYPAL_CARD_PAYPAL_PAYMENT"}] [{$lastdigits}] + [{/if}] + + +
    +
  • + [{/foreach}] +
+
+
+[{/if}] From 5a5dfd1c0462091a6890f11988e6a073e5cda8b4 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Wed, 21 Feb 2024 14:50:30 +0100 Subject: [PATCH 062/265] Throw also Error on failing capture and failing execution of PayPal Payment --- src/Model/Order.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Model/Order.php b/src/Model/Order.php index 228a21c5..23075222 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -420,8 +420,6 @@ public function markOrderPaymentFailed(): void * Returns PayPal order id. * * @param string|null $oxId - * - * @return string */ public function getPayPalOrderIdForOxOrderId(string $oxId = null): string { From 3d5960e20340dde255bb6da2c94a0ce959ec66d0 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Wed, 21 Feb 2024 14:56:35 +0100 Subject: [PATCH 063/265] CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fe140bb..25a81fe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,7 +61,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [2.3.5] - 2024-??-?? -- remove Sofort and MyBank, Paymentmethods will soon no longer be accepted via PayPal +- [0007588](https://bugs.oxid-esales.com/view.php?id=7588): Improve Error handling for Capture Order Requests (thanks to mount7) ## [2.3.4] - 2024-01-26 From df03496b64d8eae2b3d26713a68d20401c9b431f Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Wed, 21 Feb 2024 15:00:48 +0100 Subject: [PATCH 064/265] take over from OXID7 --- src/Model/Order.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Model/Order.php b/src/Model/Order.php index 23075222..78f48e23 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -263,6 +263,9 @@ protected function afterOrderCleanUp(Basket $basket, User $user): void // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore protected function executePayment(Basket $basket, $userpayment) { + //order number needs to be set before the payment is requested + $this->setOrderNumber(); + $paymentService = $this->getServiceFromContainer(PaymentService::class); $sessionPaymentId = (string) $paymentService->getSessionPaymentId(); From e2fcb5ef560cbfc524a6d36664e86fabdf339ebe Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 23 Feb 2024 15:11:37 +0100 Subject: [PATCH 065/265] delete temporary ACDC-Order if declined --- src/Model/Order.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Model/Order.php b/src/Model/Order.php index 78f48e23..d63f6ddd 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -206,6 +206,8 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f // so we set the order to "oxtransstatus" = ERROR // The Merchant has the opportunity to see what is going on and can contact the customer if necessary $this->setOrderStatus('ERROR'); + $paymentService = $this->getServiceFromContainer(PaymentService::class); + $paymentService->removeTemporaryOrder(); throw PayPalException::cannotFinalizeOrderAfterExternalPayment($payPalOrderId, $paymentsId); } $this->setTransId($capture->id); From 4ca110db9ab740c4e3b9c1eb3c9607eb34480a03 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Thu, 29 Feb 2024 10:29:21 +0100 Subject: [PATCH 066/265] PSPAYPAL-743 - set noteToPayer as required field --- views/admin/tpl/oscpaypalorder.tpl | 243 +++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 views/admin/tpl/oscpaypalorder.tpl diff --git a/views/admin/tpl/oscpaypalorder.tpl b/views/admin/tpl/oscpaypalorder.tpl new file mode 100644 index 00000000..1d25d422 --- /dev/null +++ b/views/admin/tpl/oscpaypalorder.tpl @@ -0,0 +1,243 @@ +[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}] + +
+ [{$oViewConf->getHiddenSid()}] + + +
+ +[{if $error}] +
[{$error}]
+[{/if}] + +[{if $order && $payPalOrder}] + + [{assign var="currency" value=$oView->getPayPalCurrency()}] + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
[{oxmultilang ident="OSC_PAYPAL_SHOP_PAYMENT_STATUS" suffix="COLON"}] + [{oxmultilang ident='OSC_PAYPAL_STATUS_'|cat:$oView->getPayPalPaymentStatus()}] +
[{oxmultilang ident="OSC_PAYPAL_ORDER_PRICE" suffix="COLON"}] + [{$oView->formatPrice($oView->getPayPalTotalOrderSum())}] [{$currency}] +
[{oxmultilang ident="OSC_PAYPAL_AUTHORIZED_AMOUNT" suffix="COLON"}] + [{$oView->formatPrice($oView->getPayPalAuthorizationAmount())}] [{$currency}] +
[{oxmultilang ident="OSC_PAYPAL_CAPTURED_AMOUNT" suffix="COLON"}] + [{$oView->formatPrice($oView->getPayPalCapturedAmount())}] [{$currency}] +
[{oxmultilang ident="OSC_PAYPAL_REFUNDED_AMOUNT" suffix="COLON"}] + [{$oView->formatPrice($oView->getPayPalRefundedAmount())}] [{$currency}] +
[{oxmultilang ident="OSC_PAYPAL_CAPTURED_NET" suffix="COLON"}] + [{$oView->formatPrice($oView->getPayPalResultedAmount())}] [{$currency}] +
+
+ [{if $payPalOrderDetails->oscpaypal_order__oscpaypalpuipaymentreference->value}] + [{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI" suffix="COLON"}] + + + + + + + + + + + + + + + + + + + + + +
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_REFERENCE" suffix="COLON"}] + [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuipaymentreference->value}] +
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_BIC" suffix="COLON"}] + [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuibic->value}] +
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_IBAN" suffix="COLON"}] + [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuiiban->value}] +
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_BANKNAME" suffix="COLON"}] + [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuibankname->value}] +
[{oxmultilang ident="OSC_PAYPAL_PAYMENT_PUI_ACCOUNTHOLDER" suffix="COLON"}] + [{$payPalOrderDetails->oscpaypal_order__oscpaypalpuiaccountholdername->value}] +
+ [{/if}] +
+

[{oxmultilang ident="OSC_PAYPAL_ORDER_PRODUCTS" suffix="COLON"}]

+ + + + + + [{if $order->isNettoMode()}] + + [{else}] + + [{/if}] + + + + [{assign var="blWhite" value=""}] + [{foreach from=$order->getOrderArticles() item=listitem name=orderArticles}] + [{if $listitem->oxorderarticles__oxstorno->value == 1}] + [{assign var="listclass" value=listitem3}] + [{else}] + [{assign var="listclass" value=listitem$blWhite}] + [{/if}] + + + + + [{if $order->isNettoMode()}] + + + [{else}] + + + [{/if}] + + + [{if $blWhite == "2"}] + [{assign var="blWhite" value=""}] + [{else}] + [{assign var="blWhite" value="2"}] + [{/if}] + [{/foreach}] +
[{oxmultilang ident="GENERAL_SUM"}]   [{oxmultilang ident="GENERAL_ITEMNR"}]   [{oxmultilang ident="GENERAL_TITLE"}][{oxmultilang ident="ORDER_ARTICLE_ENETTO"}][{oxmultilang ident="ORDER_ARTICLE_EBRUTTO"}][{oxmultilang ident="GENERAL_ATALL"}][{oxmultilang ident="ORDER_ARTICLE_MWST"}]
[{$listitem->oxorderarticles__oxamount->value}][{$listitem->oxorderarticles__oxartnum->value}] + [{$listitem->oxorderarticles__oxtitle->value|oxtruncate:20:""|strip_tags}] + [{$listitem->getNetPriceFormated()}] + [{$order->oxorder__oxcurrency->value}] + [{$listitem->getTotalNetPriceFormated()}] + [{$order->oxorder__oxcurrency->value}] + [{$listitem->getBrutPriceFormated()}] + [{$order->oxorder__oxcurrency->value}] + [{$listitem->getTotalBrutPriceFormated()}] + [{$order->oxorder__oxcurrency->value}] + [{$listitem->oxorderarticles__oxvat->value}]
+
+ [{oxmultilang ident="OSC_PAYPAL_PAYMENT_HISTORY" suffix="COLON"}] + + + + + + + + + + + + + + + + + + [{foreach from=$oView->getPayPalHistory() item=listitem name=paypalHistory}] + [{cycle values='listitem,listitem2' assign='class'}] + + + + + + + + + + [{/foreach}] +
[{oxmultilang ident="OSC_PAYPAL_HISTORY_DATE"}][{oxmultilang ident="OSC_PAYPAL_HISTORY_ACTION"}][{oxmultilang ident="OSC_PAYPAL_AMOUNT"}] + [{oxmultilang ident="OSC_PAYPAL_HISTORY_PAYPAL_STATUS"}] + [{oxinputhelp ident="OSC_PAYPAL_HISTORY_PAYPAL_STATUS_HELP"}] + [{oxmultilang ident="OSC_PAYPAL_TRANSACTIONID"}][{oxmultilang ident="OSC_PAYPAL_INVOICE_ID"}][{oxmultilang ident="OSC_PAYPAL_COMMENT"}]
[{$listitem.date}][{oxmultilang ident='OSC_PAYPAL_'|cat:$listitem.action}] + [{$oView->formatPrice($listitem.amount)}] + [{$currency}] + [{oxmultilang ident='OSC_PAYPAL_STATUS_'|cat:$listitem.status}][{$listitem.transactionid}][{$listitem.invoiceid}][{$listitem.comment}]
+
+ [{if $oView->getPayPalPaymentStatus() == 'COMPLETED' && $oView->getPayPalRemainingRefundAmount()}] +
+

[{oxmultilang ident="OSC_PAYPAL_ISSUE_REFUND"}]

+
+ [{$oViewConf->getHiddenSid()}] + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ [{elseif $oView->getPayPalPaymentStatus() !== 'COMPLETED'}] +
+

[{oxmultilang ident="OSC_PAYPAL_ACTIONS" suffix="COLON"}]

+
+ [{$oViewConf->getHiddenSid()}] + + + + + +
+

[{oxmultilang ident="OSC_PAYPAL_CAPTURE_DAYS_LEFT" args=$oView->getTimeLeftForPayPalCapture()}]

+
+ [{/if}] +[{/if}] +[{include file="bottomnaviitem.tpl"}] +[{include file="bottomitem.tpl"}] From 6e008a4df76443d8832a57d02968257910920aae Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 29 Feb 2024 13:57:10 +0100 Subject: [PATCH 067/265] Take over from OXID 7.0 Branch --- src/Model/Order.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Model/Order.php b/src/Model/Order.php index d63f6ddd..e6640a56 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -190,7 +190,9 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f $this->getId(), $payPalOrderId, $paymentsId, - PayPalApiOrder::STATUS_APPROVED + PayPalApiOrder::STATUS_APPROVED, + '', + Constants::PAYPAL_TRANSACTION_TYPE_CAPTURE ); } else { // uAPM, PayPal Standard directly, PayPal Paylater From 9b0fa4b192fa6a3c12563a47260b1c5015b1ac01 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 29 Feb 2024 13:59:53 +0100 Subject: [PATCH 068/265] CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25a81fe1..03be521c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [2.3.5] - 2024-??-?? - [0007588](https://bugs.oxid-esales.com/view.php?id=7588): Improve Error handling for Capture Order Requests (thanks to mount7) +- remove Sofort and MyBank, Paymentmethods will soon no longer be accepted via PayPal +- fix: Refund only with note to Buyer (required) ## [2.3.4] - 2024-01-26 From 103c17a349559503989713fce9d2d60e0737cd49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:35:53 +0000 Subject: [PATCH 069/265] Bump actions/cache from 4.0.0 to 4.0.1 Bumps [actions/cache](https://github.com/actions/cache) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4.0.0...v4.0.1) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index 00435dec..d76b424b 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -24,7 +24,7 @@ jobs: run: git clone --depth 1 https://github.com/OXID-eSales/oxideshop_ce.git --branch b-7.0.x --single-branch source - name: Cache current installation - uses: actions/cache@v4.0.0 + uses: actions/cache@v4.0.1 with: path: | ./* @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v4.0.0 + uses: actions/cache@v4.0.1 with: path: | ./* @@ -214,7 +214,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v4.0.0 + uses: actions/cache@v4.0.1 with: path: | ./* From 022ea9ee8e3862d7e94aca83e4a1bfb27b30d913 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Tue, 5 Mar 2024 11:09:27 +0100 Subject: [PATCH 070/265] Basket total amount correction in B2B mode --- src/Core/OrderRequestFactory.php | 1 - src/Core/PatchRequestFactory.php | 1 + src/Core/PayPalRequestAmountFactory.php | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 1f4a96b7..9ca92f15 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -23,7 +23,6 @@ use OxidSolutionCatalysts\PayPal\Core\PayPalRequestAmountFactory; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\AmountBreakdown; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AmountWithBreakdown; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Item; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderApplicationContext; diff --git a/src/Core/PatchRequestFactory.php b/src/Core/PatchRequestFactory.php index 94ed8d10..994957f0 100644 --- a/src/Core/PatchRequestFactory.php +++ b/src/Core/PatchRequestFactory.php @@ -15,6 +15,7 @@ use OxidEsales\Eshop\Application\Model\Country; use OxidEsales\Eshop\Application\Model\State; use OxidEsales\Eshop\Core\Registry; +use OxidEsales\EshopCommunity\modules\osc\paypal\src\Core\PayPalRequestAmountFactory; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Item; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Patch; diff --git a/src/Core/PayPalRequestAmountFactory.php b/src/Core/PayPalRequestAmountFactory.php index 81669a1d..459a3948 100644 --- a/src/Core/PayPalRequestAmountFactory.php +++ b/src/Core/PayPalRequestAmountFactory.php @@ -72,4 +72,5 @@ public function getAmount(Basket $basket): AmountWithBreakdown return $amount; } + } From ff8d975ed3a9e6f9b92f9ed6a16d7c1441cda13d Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 5 Mar 2024 13:59:02 +0100 Subject: [PATCH 071/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03be521c..679be405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007588](https://bugs.oxid-esales.com/view.php?id=7588): Improve Error handling for Capture Order Requests (thanks to mount7) - remove Sofort and MyBank, Paymentmethods will soon no longer be accepted via PayPal - fix: Refund only with note to Buyer (required) +- [0007595](https://bugs.oxid-esales.com/view.php?id=7595): : Fix PayPal Checkout substract discount from coupon series again, if 'Show net prices in frontend (B2B)' is active ## [2.3.4] - 2024-01-26 From ce383c33dcbdb605e4ec523bf1619631cb7b65de Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 5 Mar 2024 14:10:16 +0100 Subject: [PATCH 072/265] CHANGELOG --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 679be405..325fdb76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,11 +61,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [2.3.5] - 2024-??-?? +### FIX - [0007588](https://bugs.oxid-esales.com/view.php?id=7588): Improve Error handling for Capture Order Requests (thanks to mount7) - remove Sofort and MyBank, Paymentmethods will soon no longer be accepted via PayPal - fix: Refund only with note to Buyer (required) - [0007595](https://bugs.oxid-esales.com/view.php?id=7595): : Fix PayPal Checkout substract discount from coupon series again, if 'Show net prices in frontend (B2B)' is active +### NEW +- PayPal Vaulting https://developer.paypal.com/braintree/docs/guides/paypal/checkout-with-vault/ + ## [2.3.4] - 2024-01-26 - Transfer OXID-Ordernumber to PayPal From 26a887f6786bd21061a6eaa5451e34ebca6dfee2 Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Mon, 11 Mar 2024 10:32:35 +0100 Subject: [PATCH 073/265] PSPAYPAL-746 PayPalRequestAmountFactory namespace correction --- src/Core/PatchRequestFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/PatchRequestFactory.php b/src/Core/PatchRequestFactory.php index 994957f0..b72d0cae 100644 --- a/src/Core/PatchRequestFactory.php +++ b/src/Core/PatchRequestFactory.php @@ -15,7 +15,7 @@ use OxidEsales\Eshop\Application\Model\Country; use OxidEsales\Eshop\Application\Model\State; use OxidEsales\Eshop\Core\Registry; -use OxidEsales\EshopCommunity\modules\osc\paypal\src\Core\PayPalRequestAmountFactory; +use OxidSolutionCatalysts\PayPal\Core\PayPalRequestAmountFactory; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Item; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Patch; From 62f80ff1daff82e2af50f333d6e7c7e480fd2b91 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 14 Mar 2024 13:07:56 +0100 Subject: [PATCH 074/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 325fdb76..bb2002ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - remove Sofort and MyBank, Paymentmethods will soon no longer be accepted via PayPal - fix: Refund only with note to Buyer (required) - [0007595](https://bugs.oxid-esales.com/view.php?id=7595): : Fix PayPal Checkout substract discount from coupon series again, if 'Show net prices in frontend (B2B)' is active +- use PayPal-Request-Id for every api-call ### NEW - PayPal Vaulting https://developer.paypal.com/braintree/docs/guides/paypal/checkout-with-vault/ From 93a264dc1ada60d0258b5793066b0b66e40fbaa3 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Wed, 13 Mar 2024 11:28:48 +0100 Subject: [PATCH 075/265] PSPAYPAL-747 - add PayPal-Request-Id to applicable API calls --- .../Admin/PayPalOrderController.php | 5 +++- .../Handler/CheckoutOrderApprovedHandler.php | 5 +++- src/Service/Payment.php | 25 +++++++++++-------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index d15bfc6f..d37ce256 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -228,12 +228,15 @@ public function refund(): void $order->getFieldData('oxtransid') ); + $payPalRequestId = time(); + /** @var Refund $refund */ $refund = $apiPaymentService->refundCapturedPayment( $capture->id, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + $payPalRequestId ); /** @var PaymentService $paymentService */ diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index a8d3d0db..5061f22a 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -86,12 +86,15 @@ private function capturePayment(string $orderId): OrderResponse $service = $serviceFactory->getOrderService(); $request = new OrderCaptureRequest(); + $payPalRequestId = time(); + return $service->capturePaymentForOrder( '', $orderId, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + $payPalRequestId ); } diff --git a/src/Service/Payment.php b/src/Service/Payment.php index a8a73599..ab970eef 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -147,14 +147,7 @@ public function doCreatePayPalOrder( * Set required request id if payer uses vaulted payment. * The OXID order is not created yet, so a random id will be given. */ - $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - $setVaulting = $moduleSettings->getIsVaultingActive(); - $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); - $useVaulting = $setVaulting && !is_null($selectedVaultPaymentSourceIndex); - - if ($useVaulting) { - $payPalRequestId = time(); - } + $payPalRequestId = time(); try { $response = $orderService->createOrder( @@ -270,6 +263,7 @@ public function doCapturePayPalOrder( //TODO: split into multiple methods if ($payPalOrder->intent === Constants::PAYPAL_ORDER_INTENT_AUTHORIZE) { // if order approved then authorize + $paypalRequestId = time(); if ($payPalOrder->status === ApiOrderModel::STATUS_APPROVED) { $request = new OrderAuthorizeRequest(); $payPalOrder = $orderService->authorizePaymentForOrder( @@ -277,7 +271,8 @@ public function doCapturePayPalOrder( $checkoutOrderId, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + $paypalRequestId ); } @@ -285,6 +280,7 @@ public function doCapturePayPalOrder( $authorization = $payPalOrder->purchase_units[0]->payments->authorizations[0]; $authorizationId = $authorization->id; + $paypalRequestId = time(); // check if we need a reauthorization $timeAuthorizationValidity = time() - strtotime($payPalOrder->update_time ?? '') @@ -294,7 +290,8 @@ public function doCapturePayPalOrder( $paymentService->reauthorizeAuthorizedPayment( $authorizationId, $reAuthorizeRequest, - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + $paypalRequestId ); } @@ -310,11 +307,13 @@ public function doCapturePayPalOrder( // capture $request = new CaptureRequest(); + $paypalRequestId = time(); try { $paymentService->captureAuthorizedPayment( $authorizationId, $request, - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + $paypalRequestId ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); @@ -339,6 +338,9 @@ public function doCapturePayPalOrder( $shopOrderId = $order->getFieldData('oxordernr'); } + $order->setOrderNumber(); + + $paypalRequestId = time(); try { //Patching the order with OXID order number as custom value $this->doPatchPayPalOrder( @@ -352,6 +354,7 @@ public function doCapturePayPalOrder( $checkoutOrderId, $request, '', + $paypalRequestId ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); From 88b131abe3325c85e91f2b6e291ed9c4d9548388 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 10:14:18 +0000 Subject: [PATCH 076/265] Update tag to v2.0.11 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 0b71bb77..0797f736 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.10 \ No newline at end of file +v2.0.11 \ No newline at end of file From a6d4b2aaf94c3360d98f447b1302bdb3f746ae5f Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 15 Mar 2024 11:15:47 +0100 Subject: [PATCH 077/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb2002ee..917ca5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - fix: Refund only with note to Buyer (required) - [0007595](https://bugs.oxid-esales.com/view.php?id=7595): : Fix PayPal Checkout substract discount from coupon series again, if 'Show net prices in frontend (B2B)' is active - use PayPal-Request-Id for every api-call +- use PayPal-Client v2.0.11 ### NEW - PayPal Vaulting https://developer.paypal.com/braintree/docs/guides/paypal/checkout-with-vault/ From 5d23d7cc3d3a93aedb6a6325b00419451ebfc778 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 14:11:36 +0000 Subject: [PATCH 078/265] Update tag to v2.0.12 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 0797f736..93b1c84a 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.11 \ No newline at end of file +v2.0.12 \ No newline at end of file From 8f09ccedc8c8a55532680cca48f97bf5110b8f84 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 19 Mar 2024 15:07:08 +0100 Subject: [PATCH 079/265] Use the centrally provided log functionality --- .../Admin/PayPalOrderController.php | 7 --- src/Core/Onboarding/Onboarding.php | 45 +++++++++---------- src/Service/Payment.php | 9 +--- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index d37ce256..fd158fc3 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -94,10 +94,6 @@ public function executeFunction($functionName) parent::executeFunction($functionName); } catch (ApiException $exception) { $this->addTplParam('error', $exception->getErrorDescription()); - - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); - $logger->log('error', $exception->getMessage()); } } @@ -158,9 +154,6 @@ public function render() } } catch (ApiException $exception) { $this->addTplParam('error', $lang->translateString('OSC_PAYPAL_ERROR_' . $exception->getErrorIssue())); - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); - $logger->log('error', $exception->getMessage()); } } elseif ( $order->getFieldData('oxpaymenttype') == $this->payPalPlusPaymentType && diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index 3fe64e28..d8314d40 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -7,6 +7,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Onboarding; +use JsonException; use OxidEsales\Eshop\Core\Registry; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; @@ -44,10 +45,13 @@ public function autoConfigurationFromCallback(): array return $credentials; } + /** + * @throws ApiException + * @throws OnboardingException + * @throws JsonException + */ public function fetchCredentials(): array { - $credentials = []; - $onboardingResponse = $this->getOnboardingPayload(); $this->saveSandboxMode($onboardingResponse['isSandBox']); @@ -70,15 +74,16 @@ public function fetchCredentials(): array return $credentials; } + /** + * @throws OnboardingException + * @throws JsonException + */ public function getOnboardingPayload(): array { - $response = json_decode(PayPalSession::getOnboardingPayload(), true); + $response = json_decode(PayPalSession::getOnboardingPayload(), true, 512, JSON_THROW_ON_ERROR); if ( - !is_array($response) || - !isset($response['authCode']) || - !isset($response['sharedId']) || - !isset($response['isSandBox']) + !isset($response['authCode'], $response['sharedId'], $response['isSandBox']) ) { throw OnboardingException::mandatoryDataNotFound(); } @@ -92,11 +97,13 @@ public function saveSandboxMode(bool $isSandbox): void $moduleSettings->saveSandboxMode($isSandbox); } + /** + * @throws OnboardingException + */ public function saveCredentials(array $credentials): array { if ( - !isset($credentials['client_id']) || - !isset($credentials['client_secret']) + !isset($credentials['client_id'], $credentials['client_secret']) ) { throw OnboardingException::mandatoryDataNotFound(); } @@ -144,7 +151,6 @@ public function getOnboardingClient(bool $isSandbox, bool $withCredentials = fal } /** - * @return array * @throws ApiException * @throws JsonException * @throws OnboardingException @@ -152,16 +158,7 @@ public function getOnboardingClient(bool $isSandbox, bool $withCredentials = fal public function fetchMerchantInformations(): array { $onboardingResponse = $this->getOnboardingPayload(); - try { - /** @var ApiOnboardingClient $apiClient */ - $apiClient = $this->getOnboardingClient($onboardingResponse['isSandBox'], true); - $merchantInformations = $apiClient->getMerchantInformations(); - } catch (ApiException $exception) { - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); - $logger->log('error', $exception->getMessage(), [$exception]); - } - return $merchantInformations; + return $this->getOnboardingClient($onboardingResponse['isSandBox'], true)->getMerchantInformations(); } public function saveEligibility(array $merchantInformations): array @@ -188,20 +185,20 @@ public function saveEligibility(array $merchantInformations): array foreach ($merchantInformations['products'] as $product) { if ( $product['name'] === 'PAYMENT_METHODS' && - in_array('PAY_UPON_INVOICE', $product['capabilities']) + in_array('PAY_UPON_INVOICE', $product['capabilities'], true) ) { $isPuiEligibility = true; } elseif ( $product['name'] === 'PPCP_CUSTOM' && - in_array('CUSTOM_CARD_PROCESSING', $product['capabilities']) + in_array('CUSTOM_CARD_PROCESSING', $product['capabilities'], true) ) { $isAcdcEligibility = true; } if ( + $isVaultingCapability && $product['name'] === 'PPCP_CUSTOM' && - in_array('PAYPAL_WALLET_VAULTING_ADVANCED', $product['capabilities']) && - $isVaultingCapability + in_array('PAYPAL_WALLET_VAULTING_ADVANCED', $product['capabilities'], true) ) { $isVaultingEligibility = true; } diff --git a/src/Service/Payment.php b/src/Service/Payment.php index ab970eef..8689b8f5 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -146,8 +146,9 @@ public function doCreatePayPalOrder( /* * Set required request id if payer uses vaulted payment. * The OXID order is not created yet, so a random id will be given. + * TODO: Provide an central PalRequestId based on Request-Hash */ - $payPalRequestId = time(); + $payPalRequestId = (string) time(); try { $response = $orderService->createOrder( @@ -156,11 +157,6 @@ public function doCreatePayPalOrder( $payPalClientMetadataId ); } catch (ApiException $exception) { - $this->logger->log( - 'error', - 'Api error on order create call. ' . $exception->getErrorIssue(), - [$exception] - ); $this->handlePayPalApiError($exception); } catch (Exception $exception) { $this->logger->log('error', 'Error on order create call.', [$exception]); @@ -320,7 +316,6 @@ public function doCapturePayPalOrder( $issue = $exception->getErrorIssue(); $this->displayErrorIfInstrumentDeclined($issue); - $this->logger->log('error', $exception->getMessage(), [$exception]); throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); } From a1164f74ae3dc7bd95727e7f81087b26083de9d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 09:20:44 +0000 Subject: [PATCH 080/265] Bump actions/cache from 4.0.1 to 4.0.2 Bumps [actions/cache](https://github.com/actions/cache) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v4.0.1...v4.0.2) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/development.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml index d76b424b..d0eb1034 100644 --- a/.github/workflows/development.yml +++ b/.github/workflows/development.yml @@ -24,7 +24,7 @@ jobs: run: git clone --depth 1 https://github.com/OXID-eSales/oxideshop_ce.git --branch b-7.0.x --single-branch source - name: Cache current installation - uses: actions/cache@v4.0.1 + uses: actions/cache@v4.0.2 with: path: | ./* @@ -166,7 +166,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v4.0.1 + uses: actions/cache@v4.0.2 with: path: | ./* @@ -214,7 +214,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Load current installation from cache - uses: actions/cache@v4.0.1 + uses: actions/cache@v4.0.2 with: path: | ./* From d4e0f1b60c995dc4909f9e91f244126ea683f82a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 4 Apr 2024 16:16:31 +0200 Subject: [PATCH 081/265] Release v2.4.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 917ca5b6..2c65b0d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support -## [2.3.5] - 2024-??-?? +## [2.4.0] - 2024-04-04 ### FIX - [0007588](https://bugs.oxid-esales.com/view.php?id=7588): Improve Error handling for Capture Order Requests (thanks to mount7) From 2d149c6113f0faba92c4c72dbb01e95a57512f98 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 14:16:15 +0000 Subject: [PATCH 082/265] Update tag to v2.0.13 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 93b1c84a..9949c178 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.12 \ No newline at end of file +v2.0.13 \ No newline at end of file From 380ace2bd9ea6328114a22e53d41d3e831ca6da1 Mon Sep 17 00:00:00 2001 From: "nils.baczynski@fatchip.de" Date: Tue, 9 Apr 2024 14:44:22 +0200 Subject: [PATCH 083/265] PSPAYPAL-750 remove $payPalRequestId parameters --- .../Admin/PayPalOrderController.php | 5 +--- src/Core/Api/VaultingService.php | 1 - .../Handler/CheckoutOrderApprovedHandler.php | 5 +--- src/Service/Payment.php | 23 ++++--------------- 4 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/Controller/Admin/PayPalOrderController.php b/src/Controller/Admin/PayPalOrderController.php index fd158fc3..bc868082 100644 --- a/src/Controller/Admin/PayPalOrderController.php +++ b/src/Controller/Admin/PayPalOrderController.php @@ -221,15 +221,12 @@ public function refund(): void $order->getFieldData('oxtransid') ); - $payPalRequestId = time(); - /** @var Refund $refund */ $refund = $apiPaymentService->refundCapturedPayment( $capture->id, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $payPalRequestId + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); /** @var PaymentService $paymentService */ diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index 6c9e48f1..cb94274b 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -237,7 +237,6 @@ protected function getVaultingHeaders(): array { $headers = []; $headers['Content-Type'] = 'application/json'; - $headers['PayPal-Request-Id'] = time(); $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; $headers = array_merge($headers, $this->getAuthHeaders()); return $headers; diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index 5061f22a..a8d3d0db 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -86,15 +86,12 @@ private function capturePayment(string $orderId): OrderResponse $service = $serviceFactory->getOrderService(); $request = new OrderCaptureRequest(); - $payPalRequestId = time(); - return $service->capturePaymentForOrder( '', $orderId, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $payPalRequestId + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } diff --git a/src/Service/Payment.php b/src/Service/Payment.php index 8689b8f5..a635578d 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -143,13 +143,6 @@ public function doCreatePayPalOrder( $response = []; - /* - * Set required request id if payer uses vaulted payment. - * The OXID order is not created yet, so a random id will be given. - * TODO: Provide an central PalRequestId based on Request-Hash - */ - $payPalRequestId = (string) time(); - try { $response = $orderService->createOrder( $request, @@ -259,7 +252,6 @@ public function doCapturePayPalOrder( //TODO: split into multiple methods if ($payPalOrder->intent === Constants::PAYPAL_ORDER_INTENT_AUTHORIZE) { // if order approved then authorize - $paypalRequestId = time(); if ($payPalOrder->status === ApiOrderModel::STATUS_APPROVED) { $request = new OrderAuthorizeRequest(); $payPalOrder = $orderService->authorizePaymentForOrder( @@ -267,8 +259,7 @@ public function doCapturePayPalOrder( $checkoutOrderId, $request, '', - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $paypalRequestId + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } @@ -276,7 +267,6 @@ public function doCapturePayPalOrder( $authorization = $payPalOrder->purchase_units[0]->payments->authorizations[0]; $authorizationId = $authorization->id; - $paypalRequestId = time(); // check if we need a reauthorization $timeAuthorizationValidity = time() - strtotime($payPalOrder->update_time ?? '') @@ -286,8 +276,7 @@ public function doCapturePayPalOrder( $paymentService->reauthorizeAuthorizedPayment( $authorizationId, $reAuthorizeRequest, - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $paypalRequestId + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } @@ -303,13 +292,11 @@ public function doCapturePayPalOrder( // capture $request = new CaptureRequest(); - $paypalRequestId = time(); try { $paymentService->captureAuthorizedPayment( $authorizationId, $request, - Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $paypalRequestId + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); @@ -335,7 +322,6 @@ public function doCapturePayPalOrder( $order->setOrderNumber(); - $paypalRequestId = time(); try { //Patching the order with OXID order number as custom value $this->doPatchPayPalOrder( @@ -348,8 +334,7 @@ public function doCapturePayPalOrder( '', $checkoutOrderId, $request, - '', - $paypalRequestId + '' ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); From dbf977b06e941ed27626765b35bf35c22221390d Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 9 Apr 2024 16:28:04 +0200 Subject: [PATCH 084/265] codestyle --- src/Controller/Admin/PayPalConfigController.php | 3 ++- src/Controller/OrderController.php | 2 +- src/Controller/PaymentController.php | 1 - src/Core/PayPalRequestAmountFactory.php | 1 - src/Core/ViewConfig.php | 13 ++++++------- src/Service/ModuleSettings.php | 2 +- src/Traits/JsonTrait.php | 2 +- 7 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index e7cd165a..2b1c0644 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -129,7 +129,8 @@ private function buildSignUpLink( 'secondaryProducts' => 'advanced_vaulting,payment_methods', 'capabilities' => 'GOOGLE_PAY,APPLE_PAY,PAY_UPON_INVOICE,PAYPAL_WALLET_VAULTING_ADVANCED', 'integrationType' => 'FO', - 'features' => 'PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,ADVANCED_TRANSACTIONS_SEARCH,VAULT,BILLING_AGREEMENT', + 'features' => + 'PAYMENT,REFUND,ACCESS_MERCHANT_INFORMATION,ADVANCED_TRANSACTIONS_SEARCH,VAULT,BILLING_AGREEMENT', 'country.x' => $countryCode, 'locale.x' => $localeCode, 'sellerNonce' => $this->createNonce(), diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 20c76c6d..36a85db5 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -83,7 +83,7 @@ public function render() $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); if ($moduleSettings->getIsVaultingActive() && $this->getUser()->oxuser__oxpassword->value) { - $this->addTplParam('oscpaypal_payment_saveable',true); + $this->addTplParam('oscpaypal_payment_saveable', true); } $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index f1b76965..bf9e3fa8 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -41,7 +41,6 @@ public function render() if ($paypalCustomerId = $this->getUser()->getFieldData("oscpaypalcustomerid")) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { - $vaultedPaymentSources = []; foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { diff --git a/src/Core/PayPalRequestAmountFactory.php b/src/Core/PayPalRequestAmountFactory.php index 459a3948..81669a1d 100644 --- a/src/Core/PayPalRequestAmountFactory.php +++ b/src/Core/PayPalRequestAmountFactory.php @@ -72,5 +72,4 @@ public function getAmount(Basket $basket): AmountWithBreakdown return $amount; } - } diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index be5faaa2..8d597dde 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -570,16 +570,16 @@ public function getGenerateSetupTokenLink($card = false) $config = oxNew(Config::class); $params = 'cl=osctokencontroller&fnc=generatesetuptoken'; if ($config->isSandbox()) { - $params.= '&XDEBUG_SESSION_START=1'; + $params .= '&XDEBUG_SESSION_START=1'; } - if($card) { - $params.= '&card=true'; + if ($card) { + $params .= '&card=true'; } $url = html_entity_decode($this->getConfig()->getShopHomeUrl()); - return $url.$params; + return $url . $params; } public function getGeneratePaymentTokenLink() @@ -587,12 +587,11 @@ public function getGeneratePaymentTokenLink() $config = oxNew(Config::class); $params = 'cl=osctokencontroller&fnc=generatepaymenttoken'; if ($config->isSandbox()) { - $params.= '&XDEBUG_SESSION_START=1'; + $params .= '&XDEBUG_SESSION_START=1'; } $url = html_entity_decode($this->getConfig()->getShopHomeUrl()); - return $url.$params.'&token='; - + return $url . $params . '&token='; } } diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 69c25e1f..008b068f 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -160,7 +160,7 @@ public function isPuiEligibility(): bool public function isVaultingEligibility(): bool { - return $this->isSandbox()? + return $this->isSandbox() ? $this->isSandBoxVaultingEligibility() : $this->isLiveVaultingEligibility(); } diff --git a/src/Traits/JsonTrait.php b/src/Traits/JsonTrait.php index 3286ed8b..8e622499 100644 --- a/src/Traits/JsonTrait.php +++ b/src/Traits/JsonTrait.php @@ -25,4 +25,4 @@ protected function outputJson($response) $utils->showMessageAndExit(json_encode($response)); } -} \ No newline at end of file +} From 6ba81d55178973a2df5f93aa048f6e6c7fd6412e Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 9 Apr 2024 16:28:33 +0200 Subject: [PATCH 085/265] Update PayPal-Client v2.0.13 --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c65b0d0..0723b6eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support +## [2.4.1] - 2024-??-?? + +- PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore +- use PayPal-Client v2.0.13 + ## [2.4.0] - 2024-04-04 ### FIX @@ -67,7 +72,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - fix: Refund only with note to Buyer (required) - [0007595](https://bugs.oxid-esales.com/view.php?id=7595): : Fix PayPal Checkout substract discount from coupon series again, if 'Show net prices in frontend (B2B)' is active - use PayPal-Request-Id for every api-call -- use PayPal-Client v2.0.11 +- use PayPal-Client v2.0.12 ### NEW - PayPal Vaulting https://developer.paypal.com/braintree/docs/guides/paypal/checkout-with-vault/ From 109aba15e52e67f75d9760bf9569f22f7098ec5b Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 16 Apr 2024 08:47:25 +0200 Subject: [PATCH 086/265] fix possible maintenance-mode --- src/Controller/PaymentController.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index bf9e3fa8..28261d3c 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -38,17 +38,21 @@ public function render() $paymentService->removeTemporaryOrder(); } - if ($paypalCustomerId = $this->getUser()->getFieldData("oscpaypalcustomerid")) { + $user = $this->getUser(); + if ( + $user && + ($paypalCustomerId = $user->getFieldData("oscpaypalcustomerid")) + ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { $vaultedPaymentSources = []; foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { - if ($paymentType == "card") { + if ($paymentType === "card") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_ENDING_IN"); $vaultedPaymentSources[$paymentType][] = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; - } elseif ($paymentType == "paypal") { + } elseif ($paymentType === "paypal") { $string = Registry::getLang()->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); $vaultedPaymentSources[$paymentType][] = $string . " " . $paymentSource["email_address"]; } From 03f9e29499d8431847419e7c2cbdd7396527e010 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 13:40:09 +0000 Subject: [PATCH 087/265] Update tag to v2.0.14 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 9949c178..4e93974d 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.13 \ No newline at end of file +v2.0.14 \ No newline at end of file From 7faf87adc32f5116bca24bcae7e360b00c6fd144 Mon Sep 17 00:00:00 2001 From: volker Date: Mon, 11 Mar 2024 10:01:00 +0100 Subject: [PATCH 088/265] PSPAYPAL-685 - add googlepay --- metadata.php | 3 + src/Controller/ProxyController.php | 185 ++++++++++++++++++ src/Core/PayPalDefinitions.php | 23 +++ src/Core/ViewConfig.php | 31 ++- ...ductmain__details_productmain_tobasket.tpl | 1 + 5 files changed, 242 insertions(+), 1 deletion(-) diff --git a/metadata.php b/metadata.php index 322ae66b..5c7b468a 100755 --- a/metadata.php +++ b/metadata.php @@ -146,6 +146,9 @@ // PSPAYPAL-491 Installment banners 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', + + // PSPAYPAL-685 Installment banners + 'modules/osc/paypal/googlepay.tpl' => 'osc/paypal/views/tpl/shared/googlepay.tpl', //PSPAYPAL-680 Vaulting 'modules/osc/paypal/account_vaulting_paypal.tpl' => 'osc/paypal/views/tpl/shared/page/account/account_vaulting_paypal.tpl', diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index c655728f..7641b8b9 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -89,6 +89,191 @@ public function createOrder() $this->outputJson($response); } + + public function getGooglepayBasket() + { + $basket = Registry::getSession()->getBasket(); + $lang = Registry::getLang(); + $actShopCurrency = Registry::getConfig()->getActShopCurrencyObject(); + + if ($basket->getItemsCount() === 0) { + $this->addToBasket(); + + $basket = Registry::getSession()->getBasket(); + $blIsAdd = true; + } + + $this->setPayPalPaymentMethod(); + + $sVat = 0; + foreach ($basket->getProductVats(false) as $key => $VATitem ){ + $sVat += $VATitem; + } + + $aItems = [ + "displayItems" => [ + [ + "label" => $lang->translateString("TOTAL_NET"), + "type" => "SUBTOTAL", + "price" => number_format((double) $basket->getNettoSum(), 2, '.', ''), + ], + [ + "label" => $lang->translateString("VAT"), + "type" => "TAX", + "price" => number_format((double) $sVat, 2, '.', ''), + ], + [ + "label" => $lang->translateString("SHIPPING"), + "type" => "LINE_ITEM", + "price" => number_format((double) $basket->getDeliveryCosts(), 2, '.', ''), + "status" => "PENDING" + ] + ], + "countryCode" => strtoupper($lang->getLanguageAbbr()), + "currencyCode" => strtoupper($actShopCurrency->name), + "totalPriceStatus" => "ESTIMATED", + "totalPrice" => number_format((double) $basket->getBruttoSum(), 2, '.', ''), + "totalPriceLabel" => $lang->translateString("TOTAL"), + ]; + + if( $blIsAdd ){ + if ($aid = (string)Registry::getRequest()->getRequestEscapedParameter('aid')) { + try { + $basket->addToBasket($aid, 0); + $basket->calculateBasket(false); + } + catch (NoArticleException $exception) { + } + } + } + + $utils = Registry::getUtils(); + $utils->showMessageAndExit(json_encode($aItems)); + } + + public function createGooglepayOrder() + { + $data = json_decode( file_get_contents( 'php://input' ), true ); + + $billingAddress = new AddressPortable(); + $billingAddress->address_line_1 = $data['paymentMethodData']['info']['billingAddress']['address1'] ?? ''; + $billingAddress->address_line_2 = $data['paymentMethodData']['info']['billingAddress']['address2'] ?? ''; + $billingAddress->address_line_3 = $data['paymentMethodData']['info']['billingAddress']['address3'] ?? ''; + $billingAddress->postal_code = $data['paymentMethodData']['info']['billingAddress']['postalCode'] ?? ''; + $billingAddress->admin_area_2 = $data['paymentMethodData']['info']['billingAddress']['locality'] ?? ''; + $billingAddress->admin_area_1 = $data['paymentMethodData']['info']['billingAddress']['administrativeArea'] ?? ''; + $billingAddress->country_code = $data['paymentMethodData']['info']['billingAddress']['countryCode'] ?? ''; + + $shippingAddress = new AddressPortable(); + $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; + $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; + $shippingAddress->address_line_3 = $data['shippingAddress']['address3'] ?? ''; + $shippingAddress->postal_code = $data['shippingAddress']['postalCode'] ?? ''; + $shippingAddress->admin_area_2 = $data['shippingAddress']['locality'] ?? ''; + $shippingAddress->admin_area_1 = $data['shippingAddress']['administrativeArea'] ?? ''; + $shippingAddress->country_code = $data['shippingAddress']['countryCode'] ?? ''; + + if (PayPalSession::isPayPalExpressOrderActive()) { + //TODO: improve + $this->outputJson(['ERROR' => 'PayPal session already started.' . PayPalSession::isPayPalExpressOrderActive() ]); + } + + $this->addToBasket(); + $this->setPayPalPaymentMethod(); + $basket = Registry::getSession()->getBasket(); + + if ($basket->getItemsCount() === 0) { + $this->outputJson(['ERROR' => 'No Article in the Basket']); + } + + $response = $this->getServiceFromContainer(PaymentService::class)->doCreatePayPalOrder( + $basket, + OrderRequest::INTENT_AUTHORIZE, + OrderRequestFactory::USER_ACTION_CONTINUE, + null, + '', + '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, + null, + null, + false, + false, + null + ); + + if ($response->id) { + PayPalSession::storePayPalOrderId($response->id); + } + + if (!$this->getUser()) { + + $purchaseUnitRequest = new PurchaseUnitRequest(); + $purchaseUnitRequest->shipping->address = $shippingAddress; + $purchaseUnitRequest->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; + + $response->purchase_units = [$purchaseUnitRequest]; + + $response->payer = new Payer(); + $response->payer->email_address = $data['email']; + $response->payer->phone->phone_number->national_number = $data['shippingAddress']['phoneNumber'] ?? ''; + $response->payer->address = $billingAddress; + + $userRepository = $this->getServiceFromContainer(UserRepository::class); + $paypalEmail = $data['email']; + + $nonGuestAccountDetected = false; + if ($userRepository->userAccountExists($paypalEmail)) { + //got a non-guest account, so either we log in or redirect customer to login step + $isLoggedIn = $this->handleUserLogin($response); + $nonGuestAccountDetected = true; + } else { + //we need to use a guest account + $userComponent = oxNew(UserComponent::class); + $userComponent->createPayPalGuestUser($response); + } + } + + if ($user = $this->getUser()) { + /** @var array $userInvoiceAddress */ + $userInvoiceAddress = $user->getInvoiceAddress(); + // add PayPal-Address as Delivery-Address + + $response->purchase_units[0]->shipping->address = $shippingAddress; + $response->purchase_units[0]->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; + $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); + try { + $user->changeUserData( + $user->oxuser__oxusername->value, + '', + '', + $userInvoiceAddress, + $deliveryAddress + ); + + // use a deliveryaddress in oxid-checkout + Registry::getSession()->setVariable('blshowshipaddress', false); + + $this->setPayPalPaymentMethod(); + } catch (StandardException $exception) { + Registry::getUtilsView()->addErrorToDisplay($exception); + $response->status = 'ERROR'; + PayPalSession::unsetPayPalOrderId(); + Registry::getSession()->getBasket()->setPayment(null); + } + } elseif ($nonGuestAccountDetected && !$isLoggedIn) { + // PPExpress is actual no possible so we switch to PP-Standard + $this->setPayPalPaymentMethod(PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID); + } else { + //TODO: we might end up in order step redirecting to start page without showing a message + // if we have no user, we stop the process + $response->status = 'ERROR'; + PayPalSession::unsetPayPalOrderId(); + Registry::getSession()->getBasket()->setPayment(null); + } + + $this->outputJson($response); + } + public function approveOrder() { diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index e70aff40..01f5b82e 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -20,6 +20,7 @@ final class PayPalDefinitions public const GIROPAY_PAYPAL_PAYMENT_ID = 'oscpaypal_giropay'; public const SEPA_PAYPAL_PAYMENT_ID = 'oscpaypal_sepa'; public const CCALTERNATIVE_PAYPAL_PAYMENT_ID = 'oscpaypal_cc_alternative'; + public const GOOGLEPAY_PAYPAL_PAYMENT_ID = 'oscpaypal_googlepay'; //vaulting public const PAYMENT_VAULTING = [ @@ -69,6 +70,28 @@ final class PayPalDefinitions 'buttonpayment' => false, 'defaulton' => true ], + //GooglePay + self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ + 'descriptions' => [ + 'de' => [ + 'desc' => 'GooglePay', + 'longdesc' => '', + 'longdesc_beta' => 'Bezahlen Sie bequem mit GooglePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' + ], + 'en' => [ + 'desc' => 'GooglePay', + 'longdesc' => '', + 'longdesc_beta' => 'Pay conveniently with GooglePay. Start directly from the details page or in the shopping cart.' + ] + ], + 'countries' => [], + 'currencies' => ['AUD', 'BRL', 'CAD', 'CNY', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MYR', 'MXN', 'TWD', 'NZD', 'NOK', 'PHP', 'PLN', 'GBP', 'RUB', 'SGD', 'SEK', 'CHF', 'THB', 'USD'], + 'uapmpaymentsource' => 'googlepay', + 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, + 'onlybrutto' => false, + 'buttonpayment' => false, + 'defaulton' => true + ], //Paylater PayPal self::PAYLATER_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 8d597dde..2b2e09aa 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -148,6 +148,35 @@ public function getCancelPayPalPaymentUrl(): string { return $this->getSslSelfLink() . 'cl=oscpaypalproxy&fnc=cancelPayPalPayment'; } + + /** + * Gets PayPalGooglepay JS SDK url + * + * @return string + */ + public function getPayPalJsSdkGooglepayUrl(): string + { + $config = Registry::getConfig(); + $lang = Registry::getLang(); + + $localeCode = $this->getServiceFromContainer(LanguageLocaleMapper::class) + ->mapLanguageToLocale($lang->getLanguageAbbr()); + + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $params = []; + + $params['client-id'] = $this->getPayPalClientId(); + + if ($currency = $config->getActShopCurrencyObject()) { + $params['currency'] = strtoupper($currency->name); + } + + $params['components'] = 'googlepay'; + $params['merchant-id'] = $moduleSettings->getMerchantId(); + $params['buyer-country'] = strtoupper($lang->getLanguageAbbr()); + + return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); + } /** * Gets PayPal JS SDK url @@ -174,7 +203,7 @@ public function getPayPalJsSdkUrl(): string $params['currency'] = strtoupper($currency->name); } - $params['components'] = 'buttons'; + $params['components'] = 'buttons,googlepay'; // Available components: enable messages+buttons for PDP if ($this->isPayPalBannerActive()) { $params['components'] .= ',messages'; diff --git a/views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl b/views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl index 1bd681a9..37859b58 100644 --- a/views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl +++ b/views/smarty/frontend/blocks/page/details/inc/productmain__details_productmain_tobasket.tpl @@ -2,4 +2,5 @@ [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] [{if $blCanBuy && !$oDetailsProduct->isNotBuyable() && $config->isActive() && !$oViewConf->isPayPalExpressSessionActive() && $config->showPayPalProductDetailsButton()}] [{include file="@osc_paypal/frontend/paymentbuttons.tpl" buttonId="PayPalButtonProductMain" buttonClass="paypal-button-wrapper large" aid=$oDetailsProduct->oxarticles__oxid->value}] + [{include file="modules/osc/paypal/googlepay.tpl" buttonId="PayPalButtonProductMain" buttonClass="paypal-button-wrapper large" aid=$oDetailsProduct->oxarticles__oxid->value}] [{/if}] From 0ca9430300dd30bbec5c64f9f9d51213fab1f84a Mon Sep 17 00:00:00 2001 From: volker Date: Mon, 11 Mar 2024 10:19:11 +0100 Subject: [PATCH 089/265] PSPAYPAL-685 - create googlepay.tpl --- views/smarty/frontend/blocks/googlepay.tpl | 191 +++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 views/smarty/frontend/blocks/googlepay.tpl diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl new file mode 100644 index 00000000..15235e2a --- /dev/null +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -0,0 +1,191 @@ +[{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] +[{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] +[{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] + + +[{oxscript add=$smarty.capture.detailsGooglePayScript}] + From 718df1d16308f31b374c464edc6b525283bbdd5a Mon Sep 17 00:00:00 2001 From: volker Date: Tue, 12 Mar 2024 22:03:28 +0100 Subject: [PATCH 090/265] PSPAYPAL-685 - add googlepay on payment --- metadata.php | 3 ++- src/Controller/ProxyController.php | 8 ++++++++ views/blocks/page/checkout/select_payment.tpl | 15 +++++++++++++++ views/smarty/frontend/blocks/googlepay.tpl | 1 - views/smarty/frontend/google_pay.tpl | 7 +++++++ 5 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 views/blocks/page/checkout/select_payment.tpl create mode 100644 views/smarty/frontend/google_pay.tpl diff --git a/metadata.php b/metadata.php index 5c7b468a..980921c0 100755 --- a/metadata.php +++ b/metadata.php @@ -119,7 +119,8 @@ 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', - 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', + 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/google_pay.tpl', + 'modules/osc/paypal/google_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 7641b8b9..f3b08e5d 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -33,6 +33,13 @@ use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiOrder; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\PurchaseUnitRequest; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\Payer; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\Phone as ApiModelPhone; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\PhoneWithType; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\ShippingDetail; /** * Server side interface for PayPal smart buttons. @@ -193,6 +200,7 @@ public function createGooglepayOrder() null, '', '', + '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, null, null, diff --git a/views/blocks/page/checkout/select_payment.tpl b/views/blocks/page/checkout/select_payment.tpl new file mode 100644 index 00000000..2cf36427 --- /dev/null +++ b/views/blocks/page/checkout/select_payment.tpl @@ -0,0 +1,15 @@ +[{if $sPaymentID == "oscpaypal_express"}] + [{include file='modules/osc/paypal/select_payment.tpl'}] +[{elseif $sPaymentID == "oscpaypal_sepa" || $sPaymentID == "oscpaypal_cc_alternative"}] + [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] + [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] + [{include file="modules/osc/paypal/sepa_cc_alternative.tpl" sPaymentID=$sPaymentID}] + [{/if}] +[{elseif $sPaymentID == "oscpaypal_googlepay"}] + [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] + [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] + [{include file="modules/osc/paypal/google_pay.tpl" sPaymentID=$sPaymentID}] + [{/if}] +[{else}] + [{$smarty.block.parent}] +[{/if}] diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 15235e2a..12cf2d78 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -125,7 +125,6 @@ function onGooglePayLoaded() { function addGooglePayButton() {   const paymentsClient = getGooglePaymentsClient();   const button = paymentsClient.createButton({ "buttonType": "buy", - "buttonSizeMode": "fill", "buttonLocale": "[{$oView->getActiveLangAbbr()|oxlower}]", "onClick": onGooglePaymentButtonClicked }); diff --git a/views/smarty/frontend/google_pay.tpl b/views/smarty/frontend/google_pay.tpl new file mode 100644 index 00000000..fde2aca9 --- /dev/null +++ b/views/smarty/frontend/google_pay.tpl @@ -0,0 +1,7 @@ +
+
+ [{include file="modules/osc/paypal/select_payment.tpl"}] + + [{include file="modules/osc/paypal/googlepay.tpl" buttonId=$sPaymentID buttonClass="paypal-button-wrapper large"}] +
+
From de54ffcdad52be99639d0f1d62f484e635b314ba Mon Sep 17 00:00:00 2001 From: volker Date: Wed, 13 Mar 2024 23:58:43 +0100 Subject: [PATCH 091/265] PSPAYPAL-685 - googlepay.tpl adjustments --- src/Controller/ProxyController.php | 13 +-- views/smarty/frontend/blocks/googlepay.tpl | 81 +++++++++++++++---- .../frontend/blocks/layout/base__base_js.tpl | 2 +- 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index f3b08e5d..7e08e6da 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -40,7 +40,7 @@ use OxidSolutionCatalysts\PayPalApi\Model\Orders\Phone as ApiModelPhone; use OxidSolutionCatalysts\PayPalApi\Model\Orders\PhoneWithType; use OxidSolutionCatalysts\PayPalApi\Model\Orders\ShippingDetail; - + /** * Server side interface for PayPal smart buttons. */ @@ -161,16 +161,7 @@ public function getGooglepayBasket() public function createGooglepayOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - - $billingAddress = new AddressPortable(); - $billingAddress->address_line_1 = $data['paymentMethodData']['info']['billingAddress']['address1'] ?? ''; - $billingAddress->address_line_2 = $data['paymentMethodData']['info']['billingAddress']['address2'] ?? ''; - $billingAddress->address_line_3 = $data['paymentMethodData']['info']['billingAddress']['address3'] ?? ''; - $billingAddress->postal_code = $data['paymentMethodData']['info']['billingAddress']['postalCode'] ?? ''; - $billingAddress->admin_area_2 = $data['paymentMethodData']['info']['billingAddress']['locality'] ?? ''; - $billingAddress->admin_area_1 = $data['paymentMethodData']['info']['billingAddress']['administrativeArea'] ?? ''; - $billingAddress->country_code = $data['paymentMethodData']['info']['billingAddress']['countryCode'] ?? ''; - + $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 12cf2d78..d58f856e 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -4,25 +4,21 @@ [{oxscript add=$smarty.capture.detailsGooglePayScript}] diff --git a/views/smarty/frontend/blocks/layout/base__base_js.tpl b/views/smarty/frontend/blocks/layout/base__base_js.tpl index 82dcb6f1..91418182 100644 --- a/views/smarty/frontend/blocks/layout/base__base_js.tpl +++ b/views/smarty/frontend/blocks/layout/base__base_js.tpl @@ -20,7 +20,7 @@ [{elseif $className == 'order' && $oViewConf->isPayPalACDCSessionActive()}] [{elseif $className == 'payment' || $className == 'oscaccountvaultcard'}] - + [{elseif $className == 'oscaccountvault'}] [{elseif $oViewConf->isPayPalBannerActive() && ($className == 'start' || $className == 'search' || $className == 'details' || $className == 'alist' || $className == 'basket')}] From 7f1d786c9ae9b489a17fda19249af1d9fb1c8d32 Mon Sep 17 00:00:00 2001 From: volker Date: Mon, 18 Mar 2024 00:27:16 +0100 Subject: [PATCH 092/265] PSPAYPAL-685 - googlepay.tpl adjustments --- src/Controller/PaymentController.php | 10 +++ src/Controller/ProxyController.php | 9 ++- views/smarty/frontend/blocks/googlepay.tpl | 93 ++++++++++++---------- views/smarty/frontend/google_pay.tpl | 1 + 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 28261d3c..dc4c6f82 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -68,6 +68,16 @@ public function render() return parent::render(); } + + public function getPayPalPuiFraudnetCmId(): string + { + + if (!($cmId = \OxidSolutionCatalysts\PayPal\Core\PayPalSession::getPayPalPuiCmId())) { + $cmId = Registry::getUtilsObject()->generateUId(); + \OxidSolutionCatalysts\PayPal\Core\PayPalSession::storePayPalPuiCmId($cmId); + } + return $cmId; + } /** * Template variable getter. Returns paymentlist diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 7e08e6da..83c4d03c 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -161,7 +161,9 @@ public function getGooglepayBasket() public function createGooglepayOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - + + #error_log( serialize($data) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_json.txt" ); + $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; @@ -203,7 +205,8 @@ public function createGooglepayOrder() if ($response->id) { PayPalSession::storePayPalOrderId($response->id); } - + #error_log( serialize($response) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_response.txt" ); + if (!$this->getUser()) { $purchaseUnitRequest = new PurchaseUnitRequest(); @@ -269,7 +272,7 @@ public function createGooglepayOrder() PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); } - + #error_log( serialize($response) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_id.txt" ); $this->outputJson($response); } diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index d58f856e..0c1e5810 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -4,7 +4,7 @@ [{oxscript add=$smarty.capture.detailsGooglePayScript}] diff --git a/views/smarty/frontend/google_pay.tpl b/views/smarty/frontend/google_pay.tpl index fde2aca9..94f9ba77 100644 --- a/views/smarty/frontend/google_pay.tpl +++ b/views/smarty/frontend/google_pay.tpl @@ -2,6 +2,7 @@
[{include file="modules/osc/paypal/select_payment.tpl"}] +
[{include file="modules/osc/paypal/googlepay.tpl" buttonId=$sPaymentID buttonClass="paypal-button-wrapper large"}]
From 20e4b20ef9afff730e2d56025dea842686d51da6 Mon Sep 17 00:00:00 2001 From: volker Date: Wed, 27 Mar 2024 11:41:18 +0100 Subject: [PATCH 093/265] PSPAYPAL-685 - googlepay.tpl adjustments --- src/Controller/OrderController.php | 3 +- src/Controller/ProxyController.php | 5 +- src/Core/ViewConfig.php | 2 +- views/smarty/frontend/blocks/googlepay.tpl | 126 +++++++++++++-------- 4 files changed, 81 insertions(+), 55 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 36a85db5..796dd829 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -76,7 +76,8 @@ public function render() $paymentService->getSessionPaymentId() === PayPalDefinitions::SEPA_PAYPAL_PAYMENT_ID || $paymentService->getSessionPaymentId() === PayPalDefinitions::CCALTERNATIVE_PAYPAL_PAYMENT_ID || $paymentService->getSessionPaymentId() === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID || - $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID + $paymentService->getSessionPaymentId() === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID || + $paymentService->getSessionPaymentId() === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID ) { $paymentService->removeTemporaryOrder(); } diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 83c4d03c..c69c7a3f 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -162,8 +162,6 @@ public function createGooglepayOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - #error_log( serialize($data) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_json.txt" ); - $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; @@ -205,7 +203,6 @@ public function createGooglepayOrder() if ($response->id) { PayPalSession::storePayPalOrderId($response->id); } - #error_log( serialize($response) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_response.txt" ); if (!$this->getUser()) { @@ -272,7 +269,7 @@ public function createGooglepayOrder() PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); } - #error_log( serialize($response) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "creategooglepayorder_id.txt" ); + $this->outputJson($response); } diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 2b2e09aa..c4ad6fba 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -271,7 +271,7 @@ protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): str $params['commit'] = 'false'; } - $params['components'] = 'buttons,' . $type; + $params['components'] = 'buttons,googlepay,' . $type; if ($this->isPayPalBannerActive()) { $params['components'] .= ',messages'; diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 0c1e5810..0d95924f 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -20,22 +20,22 @@ getGooglePayConfig().then(Config => { }); */ -const baseRequest = { "apiVersion": 2, "apiVersionMinor": 0 }; +const baseRequest = { 'apiVersion': 2, 'apiVersionMinor': 0 }; -const allowedCardNetworks = ["MASTERCARD", "DISCOVER", "VISA", "AMEX"]; +const allowedCardNetworks = ['MASTERCARD', 'DISCOVER', 'VISA', 'AMEX']; -const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; +const allowedCardAuthMethods = ['PAN_ONLY', 'CRYPTOGRAM_3DS']; -const tokenizationSpecification = { "type": "PAYMENT_GATEWAY", "parameters": { "gateway": "paypalsb", "gatewayMerchantId": "[{$config->getMerchantId()}]" }}; +const tokenizationSpecification = { 'type': 'PAYMENT_GATEWAY', 'parameters': { 'gateway': 'paypalsb', 'gatewayMerchantId': '[{$config->getMerchantId()}]' }}; const baseCardPaymentMethod = { -  "type": "CARD", -  "parameters": { -    "allowedAuthMethods": allowedCardAuthMethods, -    "allowedCardNetworks": allowedCardNetworks, - "billingAddressRequired": true, - "assuranceDetailsRequired": true, - "billingAddressParameters": { "format": "FULL" } +  'type': 'CARD', +  'parameters': { +    'allowedAuthMethods': allowedCardAuthMethods, +    'allowedCardNetworks': allowedCardNetworks, + 'billingAddressRequired': true, + 'assuranceDetailsRequired': true, + 'billingAddressParameters': { 'format': 'FULL' }   } }; @@ -43,7 +43,7 @@ const cardPaymentMethod = Object.assign(   {},   baseCardPaymentMethod,   { -    "tokenizationSpecification": tokenizationSpecification +    'tokenizationSpecification': tokenizationSpecification   } ); @@ -53,29 +53,17 @@ function getGoogleIsReadyToPayRequest() {   return Object.assign(       {},       baseRequest, -      { "allowedPaymentMethods": [baseCardPaymentMethod] } +      { 'allowedPaymentMethods': [baseCardPaymentMethod] }   ); } -function getGooglePaymentDataRequest() { -  const paymentDataRequest = Object.assign({}, baseRequest ); - -  paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod]; -  paymentDataRequest.merchantInfo = { "merchantId": "[{$config->getMerchantId()}]", "merchantName": [{$oxcmp_shop->oxshops__oxname->value|json_encode}] }; -  paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"]; -  paymentDataRequest.emailRequired = true; - paymentDataRequest.shippingAddressRequired = true; -  paymentDataRequest.shippingAddressParameters = { "phoneNumberRequired": true }; - -  return paymentDataRequest; -} function getGooglePaymentsClient() {   if ( paymentsClient === null ) {     paymentsClient = new google.payments.api.PaymentsClient({ -        "environment": [{ if $config->isSandbox() }]"TEST"[{else}]"PRODUCTION"[{/if}], -      "paymentDataCallbacks": { "onPaymentAuthorized": onPaymentAuthorized } +        'environment': [{ if $config->isSandbox() }]'TEST'[{else}]'PRODUCTION'[{/if}], +      'paymentDataCallbacks': { 'onPaymentAuthorized': onPaymentAuthorized }     });   }   return paymentsClient; @@ -118,8 +106,22 @@ function onGooglePayLoaded() { function addGooglePayButton() {   const paymentsClient = getGooglePaymentsClient(); -  const button = paymentsClient.createButton({ "buttonType": "buy", "buttonLocale": "[{$oView->getActiveLangAbbr()|oxlower}]", "onClick": onGooglePaymentButtonClicked }); -  document.getElementById("[{$buttonId}]").appendChild(button); +  const button = paymentsClient.createButton({ 'buttonType': 'buy', 'buttonLocale': '[{$oView->getActiveLangAbbr()|oxlower}]', 'onClick': onGooglePaymentButtonClicked }); +  document.getElementById('[{$buttonId}]').appendChild(button); +} + +function getGooglePaymentDataRequest() { +  const paymentDataRequest = Object.assign({}, baseRequest ); + +  paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod]; +  paymentDataRequest.merchantInfo = { "merchantId": "[{$config->getMerchantId()}]", "merchantName": [{$oxcmp_shop->oxshops__oxname->value|json_encode}] }; + +  paymentDataRequest.callbackIntents = ['PAYMENT_AUTHORIZATION']; +  paymentDataRequest.emailRequired = true; + paymentDataRequest.shippingAddressRequired = true; +  paymentDataRequest.shippingAddressParameters = { 'phoneNumberRequired': true }; + +  return paymentDataRequest; } async function onGooglePaymentButtonClicked() { @@ -153,11 +155,12 @@ async function onGooglePaymentButtonClicked() { } async function getRespose( url = '', params ='') { - let reponse = await fetch( url, { "credentials": "same-origin", "mode": "same-origin", "method": "post", "headers": { "content-type": "application/json" }, "body": params } ) - .catch(err => { console.log(err) }); - let object = await response.json(); - console.log(object); - return object; + return await fetch( url, { "method": "post", "headers": { "content-type": "application/json" }, "body": params } ) + .then(function (res) { + return res.json(); + }).then(function (data) { + return data.id; + }); } function processPayment(paymentData) { @@ -166,30 +169,55 @@ function processPayment(paymentData) { const create_url = '[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]'; try { - const json = await getRespose( create_url, JSON.stringify(paymentData) ); - console.log(json); - + const id = await getRespose( create_url, JSON.stringify(paymentData) ); const confirmOrderResponse = paypal.Googlepay().confirmOrder({ - orderId: json.id, - paymentMethodData: paymentData.paymentMethodData + 'orderId': id, + 'paymentMethodData': paymentData.paymentMethodData }); - + + console.log(confirmOrderResponse); console.debug(confirmOrderResponse); - /** Capture the Order on your Server */ - if(confirmOrderResponse.status === "APPROVED"){ - const response = fetch('[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=dglog&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]&capture=' + json.id, { - method: 'POST', - }).then(res => res.json()); - if(response.capture.status === "COMPLETED") + + const confirmOrderPromise = Promise.resolve(confirmOrderResponse); + confirmOrderPromise.then((value) => { + console.log(value); + + if(value.status === "APPROVED" ){ + console.log('start'); + captureData = new FormData(); + captureData.append('orderID', id); + + const response = fetch('[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=approveOrder&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]&capture=' + id, + { method: 'post', body: captureData }).then(res => res.json()); + + console.log(response); + console.log('ende'); + location.replace("[{$sSelfLink|cat:"cl=order"}]"); + }; + }); + + + + /** + Capture the Order on your Server */ + if(value.status === "APPROVED"){ + captureData = new FormData(); + captureData.append('orderID', id); + + const response = fetch('[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=approveOrder&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]&capture=' + id, + { method: 'post', body: captureData }).then(res => res.json()); + + console.log(response); + if(response.capture.status === "COMPLETED") resolve({transactionState: 'SUCCESS'}); - else + else resolve({ transactionState: 'ERROR', error: { intent: 'PAYMENT_AUTHORIZATION', message: 'TRANSACTION FAILED', } - }) + }) } else { resolve({ transactionState: 'ERROR', @@ -207,7 +235,7 @@ function processPayment(paymentData) { intent: 'PAYMENT_AUTHORIZATION', message: err.message, } - }) + }); } }); } From 74f394be10ca4ee740c7680d5e5f4ea8ffac9f10 Mon Sep 17 00:00:00 2001 From: volker Date: Mon, 15 Apr 2024 00:07:29 +0200 Subject: [PATCH 094/265] PSPAYPAL-685 - googlepay.tpl adjustments --- src/Controller/ProxyController.php | 11 +- src/Core/ViewConfig.php | 1 + views/smarty/frontend/blocks/googlepay.tpl | 424 +++++++++------------ 3 files changed, 179 insertions(+), 257 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index c69c7a3f..b734fe6b 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -203,7 +203,7 @@ public function createGooglepayOrder() if ($response->id) { PayPalSession::storePayPalOrderId($response->id); } - + if (!$this->getUser()) { $purchaseUnitRequest = new PurchaseUnitRequest(); @@ -269,13 +269,15 @@ public function createGooglepayOrder() PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); } - - $this->outputJson($response); + + $this->outputJson($response); } public function approveOrder() { + $data = json_decode( file_get_contents( 'php://input' ), true ); + error_log( serialize($data) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "approveorder_json.txt" ); $orderId = (string) Registry::getRequest()->getRequestEscapedParameter('orderID'); $sessionOrderId = PayPalSession::getCheckoutOrderId(); @@ -290,7 +292,8 @@ public function approveOrder() try { $response = $service->showOrderDetails($orderId, ''); - } catch (Exception $exception) { + + } catch (Exception $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', "Error on order capture call.", [$exception]); diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index c4ad6fba..013ccbf9 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -204,6 +204,7 @@ public function getPayPalJsSdkUrl(): string } $params['components'] = 'buttons,googlepay'; + $params['merchant-id'] = $moduleSettings->getMerchantId(); // Available components: enable messages+buttons for PDP if ($this->isPayPalBannerActive()) { $params['components'] .= ',messages'; diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 0d95924f..8c641cb5 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -4,266 +4,184 @@ [{oxscript add=$smarty.capture.detailsGooglePayScript}] From db9cc570c8d929bc77ecef8c3887eeadba483720 Mon Sep 17 00:00:00 2001 From: volker Date: Tue, 16 Apr 2024 09:13:07 +0200 Subject: [PATCH 095/265] PSPAYPAL-685 - googlepay.tpl adjustments --- src/Controller/ProxyController.php | 11 +++---- views/smarty/frontend/blocks/googlepay.tpl | 35 ++++++++++------------ 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index b734fe6b..48e56d56 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -161,7 +161,7 @@ public function getGooglepayBasket() public function createGooglepayOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - + $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; @@ -203,7 +203,7 @@ public function createGooglepayOrder() if ($response->id) { PayPalSession::storePayPalOrderId($response->id); } - + if (!$this->getUser()) { $purchaseUnitRequest = new PurchaseUnitRequest(); @@ -269,15 +269,13 @@ public function createGooglepayOrder() PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); } - - $this->outputJson($response); + $this->outputJson($response); } public function approveOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - error_log( serialize($data) . "\n", 3, getShopBasePath() . "log" . DIRECTORY_SEPARATOR . date( "Ym" ) . "approveorder_json.txt" ); $orderId = (string) Registry::getRequest()->getRequestEscapedParameter('orderID'); $sessionOrderId = PayPalSession::getCheckoutOrderId(); @@ -292,8 +290,7 @@ public function approveOrder() try { $response = $service->showOrderDetails($orderId, ''); - - } catch (Exception $exception) { + } catch (Exception $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', "Error on order capture call.", [$exception]); diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 8c641cb5..8a509330 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -17,8 +17,7 @@ let paymentsClient = null, allowedPaymentMethods = null, - merchantInfo = null, - paySumInfo = null; + merchantInfo = null; /* Configure your site's support for payment methods supported by the Google Pay */ function getGoogleIsReadyToPayRequest(allowedPaymentMethods) { @@ -144,34 +143,30 @@ async function processPayment(paymentData) { try { - console.log(paymentData); - /*** Create oxid Order ***/ const createOrderUrl = '[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]'; - const { id } = await fetch(createOrderUrl, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(paymentData), - }).then((res) => res.json()); - - console.log(id); + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(paymentData), + }).then((res) => res.json()); const confirmOrderResponse = await paypal.Googlepay().confirmOrder({ orderId: id, paymentMethodData: paymentData.paymentMethodData, }); - console.log(confirmOrderResponse); - - const confirmOrderPromise = Promise.resolve(confirmOrderResponse); - console.log(confirmOrderPromise); - - console.log(status); - + if (confirmOrderResponse.status === "APPROVED") { + /*** Capture the Order ****/ + //const captureResponse = await fetch(`/orders/${id}/capture`, { + // method: "POST", + //}).then((res) => res.json()); + return { transactionState: "SUCCESS" }; + + } else { + return { transactionState: "ERROR" }; + } } catch (err) { return { From 0b57abe098db7a0b0ba0ed2552ce8d67352e5884 Mon Sep 17 00:00:00 2001 From: Danny Date: Thu, 18 Apr 2024 14:05:35 +0200 Subject: [PATCH 096/265] WIP: adding googlepay, processing order in shop, capturing order, changed button to order-site --- metadata.php | 6 +- src/Controller/OrderController.php | 137 +++++++++++++++- src/Controller/ProxyController.php | 93 ++++++----- src/Core/ConfirmOrderRequestFactory.php | 28 +++- .../PayPalAddressResponseToOxidAddress.php | 2 +- src/Model/Order.php | 9 +- .../checkout_order_btn_submit_bottom.tpl | 13 +- views/smarty/frontend/blocks/googlepay.tpl | 147 +++++++++++++----- views/smarty/frontend/google_pay.tpl | 4 +- 9 files changed, 341 insertions(+), 98 deletions(-) diff --git a/metadata.php b/metadata.php index 980921c0..7d145fcb 100755 --- a/metadata.php +++ b/metadata.php @@ -119,8 +119,8 @@ 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', - 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/google_pay.tpl', - 'modules/osc/paypal/google_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', + 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', + 'modules/osc/paypal/google_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/google_pay.tpl', 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', @@ -147,7 +147,7 @@ // PSPAYPAL-491 Installment banners 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', - + // PSPAYPAL-685 Installment banners 'modules/osc/paypal/googlepay.tpl' => 'osc/paypal/views/tpl/shared/googlepay.tpl', diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 796dd829..d99ab145 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -10,6 +10,7 @@ use Exception; use OxidEsales\Eshop\Application\Model\Order as EshopModelOrder; use OxidEsales\Eshop\Core\DisplayError; +use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; @@ -26,7 +27,10 @@ use OxidSolutionCatalysts\PayPal\Service\UserRepository; use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; +use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as ApiOrderModel; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiModelOrder; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderCaptureRequest; /** * Class OrderController @@ -179,7 +183,6 @@ public function createAcdcOrder(): void $paymentService = $this->getServiceFromContainer(PaymentService::class); $paymentService->removeTemporaryOrder(); Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID()); - $status = $this->execute(); } catch (Exception $exception) { /** @var Logger $logger */ @@ -214,6 +217,113 @@ public function createAcdcOrder(): void $this->outputJson($response); } + public function createGooglePayOrder(): void + { + $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); + $sessionAcdcOrderId = (string) PayPalSession::getCheckoutOrderId(); + $acdcStatus = Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); + + if ( + $sessionOrderId && + $sessionAcdcOrderId && + $acdcStatus === Constants::PAYPAL_STATUS_COMPLETED + ) { + //we already have a completed acdc order + $this->outputJson(['acdcerror' => 'shop order already completed']); + return; + } + + try { + $paymentService = $this->getServiceFromContainer(PaymentService::class); + $paymentService->removeTemporaryOrder(); + Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID()); + + $_POST['sDeliveryAddressMD5'] = $this->getDeliveryAddressMD5(); + $status = $this->execute(); + } catch (Exception $exception) { + /** @var Logger $logger */ + $logger = $this->getServiceFromContainer(Logger::class); + $logger->log('error', $exception->getMessage(), [$exception]); + $this->outputJson(['acdcerror' => 'failed to execute shop order']); + return; + } + + $response = $paymentService->doCreatePatchedOrder( + Registry::getSession()->getBasket() + ); + if (!($paypalOrderId = $response['id'])) { + $this->outputJson(['acdcerror' => 'cannot create paypal order']); + return; + } + + if (!$status || (PayPalOrderModel::ORDER_STATE_ACDCINPROGRESS !== (int)$status)) { + // $response = ['acdcerror' => 'unexpected order status ' . $status]; + // $paymentService->removeTemporaryOrder(); + } else { + PayPalSession::storePayPalOrderId($paypalOrderId); + $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); + $payPalOrder = $paymentService->getPayPalCheckoutOrder($sessionOrderId, $paypalOrderId); + $payPalOrder->setStatus($response['status']); + $payPalOrder->save(); + } + + $this->outputJson($response); + } + public function captureGooglePayOrder(): void + { + $orderService = Registry::get(ServiceFactory::class)->getOrderService(); + $paymentService = $this->getServiceFromContainer(PaymentService::class); + $paymentService = Registry::get(ServiceFactory::class)->getPaymentService(); + $acdcRequestId = (string) Registry::getRequest()->getRequestParameter('acdcorderid'); + $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); + $sessionAcdcOrderId = (string) PayPalSession::getCheckoutOrderId(); + $acdcStatus = Registry::getSession()->getVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); + + /** @var Logger $logger */ + $logger = $this->getServiceFromContainer(Logger::class); + $request = new OrderCaptureRequest(); + try { + /** @var $result ApiOrderModel */ + $result = $orderService->capturePaymentForOrder( + '', + $sessionAcdcOrderId, + $request, + '', + ); + } catch (ApiException $exception) { + $this->handlePayPalApiError($exception); + + $issue = $exception->getErrorIssue(); + $this->displayErrorIfInstrumentDeclined($issue); + $this->logger->log('error', $exception->getMessage(), [$exception]); + + throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'); + } + + try { + $order = oxNew(EshopModelOrder::class); + $order->setId($sessionOrderId); + $order->load($sessionOrderId); + + $result = [ + 'location' => [ + 'cl=order&fnc=finalizeGooglePay' + ] + ]; + //track status in session + Registry::getSession()->setVariable('SessionGooglePay', $sessionOrderId); + Registry::getSession()->setVariable('GooglePayOrderId', $sessionAcdcOrderId); + } catch (Exception $exception) { + $logger->log( + 'debug', + $exception->getMessage(), + [$exception] + ); + $this->getServiceFromContainer(PaymentService::class)->removeTemporaryOrder(); + } + + $this->outputJson($result); + } public function captureAcdcOrder(): void { @@ -367,7 +477,32 @@ public function finalizeacdc(): string return $goNext; } + public function finalizeGooglePay(): string + { + $sessionOrderId = Registry::getSession()->getVariable('sess_challenge'); + $sessionGooglePayOrderId = Registry::getSession()->getVariable('GooglePayOrderId'); + + $forceFetchDetails = (bool) Registry::getRequest()->getRequestParameter('fallbackfinalize'); + + try { + $order = oxNew(EshopModelOrder::class); + $order->load($sessionOrderId); + $order->finalizeOrderAfterExternalPayment($sessionGooglePayOrderId, $forceFetchDetails); + $goNext = 'thankyou'; + } catch (Exception $exception) { + /** @var Logger $logger */ + $logger = $this->getServiceFromContainer(Logger::class); + $logger->log( + 'error', + 'failure during finalizeOrderAfterExternalPayment', + [$exception] + ); + $this->cancelpaypalsession('cannot finalize order'); + $goNext = 'payment?payerror=2'; + } + return $goNext; + } public function cancelpaypalsession(string $errorcode = null): string { //TODO: we get the PayPal order id retuned in token parameter, can be used for paranoia checks diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 48e56d56..d0b119c3 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -40,7 +40,7 @@ use OxidSolutionCatalysts\PayPalApi\Model\Orders\Phone as ApiModelPhone; use OxidSolutionCatalysts\PayPalApi\Model\Orders\PhoneWithType; use OxidSolutionCatalysts\PayPalApi\Model\Orders\ShippingDetail; - + /** * Server side interface for PayPal smart buttons. */ @@ -96,7 +96,7 @@ public function createOrder() $this->outputJson($response); } - + public function getGooglepayBasket() { $basket = Registry::getSession()->getBasket(); @@ -105,18 +105,19 @@ public function getGooglepayBasket() if ($basket->getItemsCount() === 0) { $this->addToBasket(); - + $basket = Registry::getSession()->getBasket(); $blIsAdd = true; } - - $this->setPayPalPaymentMethod(); - + $deliveryCost = $basket->getDeliveryCost(); + $deliveryBruttoPrice = $deliveryCost->getBruttoPrice(); + $this->setPayPalPaymentMethod(); + $sVat = 0; foreach ($basket->getProductVats(false) as $key => $VATitem ){ $sVat += $VATitem; } - + $aItems = [ "displayItems" => [ [ @@ -132,17 +133,16 @@ public function getGooglepayBasket() [ "label" => $lang->translateString("SHIPPING"), "type" => "LINE_ITEM", - "price" => number_format((double) $basket->getDeliveryCosts(), 2, '.', ''), - "status" => "PENDING" + "price" => number_format((double) $deliveryBruttoPrice, 2, '.', ''), + "status" => "FINAL" ] ], "countryCode" => strtoupper($lang->getLanguageAbbr()), "currencyCode" => strtoupper($actShopCurrency->name), "totalPriceStatus" => "ESTIMATED", - "totalPrice" => number_format((double) $basket->getBruttoSum(), 2, '.', ''), + "totalPrice" => number_format((double) $basket->getPrice()->getBruttoPrice(), 2, '.', ''), "totalPriceLabel" => $lang->translateString("TOTAL"), ]; - if( $blIsAdd ){ if ($aid = (string)Registry::getRequest()->getRequestEscapedParameter('aid')) { try { @@ -153,19 +153,19 @@ public function getGooglepayBasket() } } } - + $utils = Registry::getUtils(); $utils->showMessageAndExit(json_encode($aItems)); } - + public function createGooglepayOrder() { $data = json_decode( file_get_contents( 'php://input' ), true ); - + $shippingAddress = new AddressPortable(); $shippingAddress->address_line_1 = $data['shippingAddress']['address1'] ?? ''; $shippingAddress->address_line_2 = $data['shippingAddress']['address2'] ?? ''; - $shippingAddress->address_line_3 = $data['shippingAddress']['address3'] ?? ''; + $shippingAddress->address_line_3 = $data['shippingAddress']['address3'] ?? ''; $shippingAddress->postal_code = $data['shippingAddress']['postalCode'] ?? ''; $shippingAddress->admin_area_2 = $data['shippingAddress']['locality'] ?? ''; $shippingAddress->admin_area_1 = $data['shippingAddress']['administrativeArea'] ?? ''; @@ -175,9 +175,10 @@ public function createGooglepayOrder() //TODO: improve $this->outputJson(['ERROR' => 'PayPal session already started.' . PayPalSession::isPayPalExpressOrderActive() ]); } + $paymentId = Registry::getSession()->getVariable('paymentid'); $this->addToBasket(); - $this->setPayPalPaymentMethod(); + $this->setPayPalPaymentMethod($paymentId); $basket = Registry::getSession()->getBasket(); if ($basket->getItemsCount() === 0) { @@ -186,7 +187,7 @@ public function createGooglepayOrder() $response = $this->getServiceFromContainer(PaymentService::class)->doCreatePayPalOrder( $basket, - OrderRequest::INTENT_AUTHORIZE, + OrderRequest::INTENT_CAPTURE, OrderRequestFactory::USER_ACTION_CONTINUE, null, '', @@ -205,18 +206,18 @@ public function createGooglepayOrder() } if (!$this->getUser()) { - + $purchaseUnitRequest = new PurchaseUnitRequest(); $purchaseUnitRequest->shipping->address = $shippingAddress; $purchaseUnitRequest->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; - + $response->purchase_units = [$purchaseUnitRequest]; - + $response->payer = new Payer(); $response->payer->email_address = $data['email']; $response->payer->phone->phone_number->national_number = $data['shippingAddress']['phoneNumber'] ?? ''; $response->payer->address = $billingAddress; - + $userRepository = $this->getServiceFromContainer(UserRepository::class); $paypalEmail = $data['email']; @@ -236,29 +237,32 @@ public function createGooglepayOrder() /** @var array $userInvoiceAddress */ $userInvoiceAddress = $user->getInvoiceAddress(); // add PayPal-Address as Delivery-Address - + $response->purchase_units[0]->shipping->address = $shippingAddress; $response->purchase_units[0]->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); - try { - $user->changeUserData( - $user->oxuser__oxusername->value, - '', - '', - $userInvoiceAddress, - $deliveryAddress - ); - - // use a deliveryaddress in oxid-checkout - Registry::getSession()->setVariable('blshowshipaddress', false); - - $this->setPayPalPaymentMethod(); - } catch (StandardException $exception) { - Registry::getUtilsView()->addErrorToDisplay($exception); - $response->status = 'ERROR'; - PayPalSession::unsetPayPalOrderId(); - Registry::getSession()->getBasket()->setPayment(null); + if ($deliveryAddress['oxaddress__oxfname'] !== '' && $deliveryAddress['oxaddress__oxstreet'] !== '') { + try { + $user->changeUserData( + $user->oxuser__oxusername->value, + '', + '', + $userInvoiceAddress, + $deliveryAddress + ); + + // use a deliveryaddress in oxid-checkout + Registry::getSession()->setVariable('blshowshipaddress', false); + + $this->setPayPalPaymentMethod(); + } catch (StandardException $exception) { + Registry::getUtilsView()->addErrorToDisplay($exception); + $response->status = 'ERROR'; + PayPalSession::unsetPayPalOrderId(); + Registry::getSession()->getBasket()->setPayment(null); + } } + } elseif ($nonGuestAccountDetected && !$isLoggedIn) { // PPExpress is actual no possible so we switch to PP-Standard $this->setPayPalPaymentMethod(PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID); @@ -325,11 +329,14 @@ public function approveOrder() $userInvoiceAddress, $deliveryAddress ); - + $paymentId = Registry::getSession()->getVariable('paymentid'); // use a deliveryaddress in oxid-checkout Registry::getSession()->setVariable('blshowshipaddress', false); - - $this->setPayPalPaymentMethod(); + if ($paymentId === 'oscpaypal_googlepay') { + $this->setPayPalPaymentMethod($paymentId); + } else { + $this->setPayPalPaymentMethod(); + } } catch (StandardException $exception) { Registry::getUtilsView()->addErrorToDisplay($exception); $response->status = 'ERROR'; diff --git a/src/Core/ConfirmOrderRequestFactory.php b/src/Core/ConfirmOrderRequestFactory.php index 11a40ace..d2ef7bb6 100644 --- a/src/Core/ConfirmOrderRequestFactory.php +++ b/src/Core/ConfirmOrderRequestFactory.php @@ -47,7 +47,7 @@ public function getRequest( return $request; } - protected function getPaymentSource(Basket $basket, string $requestName): PaymentSource + protected function getPaymentSource(Basket $basket, string $requestName) { $user = $basket->getBasketUser(); @@ -63,13 +63,27 @@ protected function getPaymentSource(Basket $basket, string $requestName): Paymen if ($deliveryId && $deliveryAddress->load($deliveryId)) { $country->load($deliveryAddress->getFieldData('oxcountryid')); } + //@todo remove the next line, until client has added googlepay + if ($requestName === 'googlepay') { + $requestName = 'google_pay'; + $paymentSource = new \stdClass(); + +// Dynamically adding properties to the stdClass object + $paymentSource->$requestName = new \stdClass(); + $paymentSource->$requestName->name = $userName; + $paymentSource->$requestName->country_code = $country->getFieldData('oxisoalpha2'); + $paymentSource->$requestName->attributes = new \stdClass(); + $paymentSource->$requestName->attributes->verification = new \stdClass(); + $paymentSource->$requestName->attributes->verification->method = 'SCA_ALWAYS'; + } else { + $paymentSource = new PaymentSource([ + $requestName => [ + 'name' => $userName, + 'country_code' => $country->getFieldData('oxisoalpha2') + ] + ]); + } - $paymentSource = new PaymentSource([ - $requestName => [ - 'name' => $userName, - 'country_code' => $country->getFieldData('oxisoalpha2') - ] - ]); return $paymentSource; } diff --git a/src/Core/Utils/PayPalAddressResponseToOxidAddress.php b/src/Core/Utils/PayPalAddressResponseToOxidAddress.php index 0b4ca487..b26d6d16 100644 --- a/src/Core/Utils/PayPalAddressResponseToOxidAddress.php +++ b/src/Core/Utils/PayPalAddressResponseToOxidAddress.php @@ -58,7 +58,7 @@ public static function mapUserInvoiceAddress( /** * @param PayPalApiOrderModel $response PayPal Response * @param string $DBTablePrefix - * @return array + * @return array|bool */ private static function mapAddress( PayPalApiOrderModel $response, diff --git a/src/Model/Order.php b/src/Model/Order.php index e6640a56..b5d0a595 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -149,11 +149,12 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f $this->afterOrderCleanUp($basket, $user); $isPayPalACDC = $paymentsId === PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; + $isPaypalGooglePay = $paymentsId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID; $isPayPalStandard = $paymentsId === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID; $transactionId = null; $payPalPaymentSuccess = true; - if ($isPayPalACDC && $forceFetchDetails) { + if ($isPayPalACDC && $forceFetchDetails || $isPaypalGooglePay) { $payPalApiOrder = $paymentService->fetchOrderFields($payPalOrderId); if ($this->isPayPalOrderCompleted($payPalApiOrder)) { $this->markOrderPaid(); @@ -171,7 +172,7 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f } } - if ($isPayPalACDC) { + if ($isPayPalACDC || $isPaypalGooglePay) { //webhook should kick in and handle order state and we should not call the api too often Registry::getSession()->deleteVariable(Constants::SESSION_ACDC_PAYPALORDER_STATUS); // remove PayPal order id from session @@ -277,7 +278,9 @@ protected function executePayment(Basket $basket, $userpayment) $isPayPalACDC = $sessionPaymentId === PayPalDefinitions::ACDC_PAYPAL_PAYMENT_ID; $isPayPalStandard = $sessionPaymentId === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID; $isPayPalPayLater = $sessionPaymentId === PayPalDefinitions::PAYLATER_PAYPAL_PAYMENT_ID; - + if ($sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { + $isPayPalUAPM = false; + } //catch UAPM, Standard and Pay Later PayPal payments here if ($isPayPalUAPM || $isPayPalStandard || $isPayPalPayLater) { try { diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index e13202da..486381eb 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -9,4 +9,15 @@ [{include file="modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl"}] [{/if}] [{/if}] -[{$smarty.block.parent}] \ No newline at end of file +[{$payment->getId()}] +[{if "oscpaypal_googlepay" == $payment->getId()}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/googlepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{else}] + [{include file="modules/osc/paypal/googlepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{/if}] +
+ +[{else}] + [{$smarty.block.parent}] +[{/if}] diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 8a509330..e896376c 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -9,21 +9,21 @@ onGooglePayLoaded().catch(console.log); } }); - + const baseRequest = { apiVersion: 2, apiVersionMinor: 0, }; - + let paymentsClient = null, allowedPaymentMethods = null, merchantInfo = null; - + /* Configure your site's support for payment methods supported by the Google Pay */ function getGoogleIsReadyToPayRequest(allowedPaymentMethods) { return Object.assign({}, baseRequest, { allowedPaymentMethods: allowedPaymentMethods, - billingAddressRequired: true, + billingAddressRequired: true, assuranceDetailsRequired: true, billingAddressParameters: { format: 'FULL' }, }); @@ -33,7 +33,7 @@ async function getGooglePayConfig() { if (allowedPaymentMethods == null || merchantInfo == null) { const googlePayConfig = await paypal.Googlepay().config(); - + allowedPaymentMethods = googlePayConfig.allowedPaymentMethods; merchantInfo = googlePayConfig.merchantInfo; merchantInfo.merchantName = [{$oxcmp_shop->oxshops__oxname->value|json_encode}]; @@ -43,35 +43,39 @@ merchantInfo, }; } - + /* Configure support for the Google Pay API */ async function getGooglePaymentDataRequest() { const paymentDataRequest = Object.assign({}, baseRequest); const { allowedPaymentMethods, merchantInfo } = await getGooglePayConfig(); - + paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods; paymentDataRequest.merchantInfo = merchantInfo; - + paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"]; - paymentDataRequest.emailRequired = true; - paymentDataRequest.shippingAddressRequired = true; -  paymentDataRequest.shippingAddressParameters = { 'phoneNumberRequired': true }; + paymentDataRequest.emailRequired = true; + paymentDataRequest.shippingAddressRequired = false; + paymentDataRequest.shippingAddressParameters = { 'phoneNumberRequired': true }; return paymentDataRequest; } - + function onPaymentAuthorized(paymentData) { return new Promise(function (resolve, reject) { processPayment(paymentData) .then(function (data) { - resolve({ transactionState: "SUCCESS" }); + console.log('onPaymentAuthorized') + console.log(data) + console.log('onPaymentAuthorized End') + + resolve({ transactionState: "SUCCESS" }); }) .catch(function (errDetails) { resolve({ transactionState: "ERROR" }); }); }); } - + function getGooglePaymentsClient() { if (paymentsClient === null) { paymentsClient = new google.payments.api.PaymentsClient({ @@ -83,7 +87,7 @@ } return paymentsClient; } - + async function onGooglePayLoaded() { const paymentsClient = getGooglePaymentsClient(); const { allowedPaymentMethods } = await getGooglePayConfig(); @@ -98,76 +102,147 @@ console.error(err); }); } - + function addGooglePayButton() { const paymentsClient = getGooglePaymentsClient(); const button = paymentsClient.createButton({ - buttonType: 'buy', + buttonType: 'buy', buttonLocale: '[{$oView->getActiveLangAbbr()|oxlower}]', onClick: onGooglePaymentButtonClicked, }); document.getElementById("[{$buttonId}]").appendChild(button); } - + async function onGooglePaymentButtonClicked() { const paymentDataRequest = await getGooglePaymentDataRequest(); - + try { const getBasketUrl = "[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=getGooglepayBasket&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]"; const basketDetails = await fetch(getBasketUrl); const json = await basketDetails.json(); - + paymentDataRequest.transactionInfo = { - displayItems: json.displayItems, + displayItems: json.displayItems, countryCode: json.countryCode, currencyCode: json.currencyCode, totalPriceStatus: json.totalPriceStatus, totalPrice: json.totalPrice, - totalPriceLabel: json.totalPriceLabel, - }; + totalPriceLabel: json.totalPriceLabel, + }; } catch (error) { console.error(error); - } - + } + const paymentsClient = getGooglePaymentsClient(); paymentsClient.loadPaymentData(paymentDataRequest) .then(function() { - //location.replace("[{$sSelfLink|cat:"cl=order"}]"); + // location.replace("[{$sSelfLink|cat:"cl=order&fnc=execute"}]"); }) .catch(err => { if( err.statusCode != "CANCELED") console.log(err) - }); + }); } - + async function processPayment(paymentData) { - try { - /*** Create oxid Order ***/ + try { + /*** Create oxid Order ***/ const createOrderUrl = '[{$sSelfLink|cat:"cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken}]'; const { id } = await fetch(createOrderUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(paymentData), - }).then((res) => res.json()); - + }).then((res) => res.json()); + const confirmOrderResponse = await paypal.Googlepay().confirmOrder({ orderId: id, paymentMethodData: paymentData.paymentMethodData, }); - + console.log('--------') + console.log(confirmOrderResponse) + console.log('--------') if (confirmOrderResponse.status === "APPROVED") { - /*** Capture the Order ****/ + console.log('approved'); + console.log(paymentData); + + function onApprove(confirmOrderResponse, actions) { + // Create a new form dynamically + var form = document.createElement("form"); + form.setAttribute("method", "post"); + form.setAttribute("action", `[{$sSelfLink|cat:"cl=order&fnc=createGooglePayOrder&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken|cat:"&sDeliveryAddressMD5="|cat:$oView->getDeliveryAddressMD5()}]`); + + // Create hidden form elements and append them to the form + var orderIDField = document.createElement("input"); + orderIDField.setAttribute("type", "hidden"); + orderIDField.setAttribute("name", "orderID"); + orderIDField.setAttribute("value", confirmOrderResponse.id); + form.appendChild(orderIDField); + + // Optional: Add more fields if needed + + // Append the form to the body + document.body.appendChild(form); + + // Submit the form + form.submit(); + + // Handle the response (Optional, as form submission will cause page reload) + form.onsubmit = function(event) { + event.preventDefault(); // Prevent the form from submitting normally + fetch(form.action, { + method: 'post', + body: new FormData(form) + }).then(function(res) { + return res.json(); + }).then(function(data) { + console.log(data); + if (data.status === "ERROR") { + location.reload(); + } else if (data.id && data.status === "APPROVED") { + // Redirect to a new URL if needed + // location.replace(`${sSelfLink}cl=order&fnc=execute`); + } + }); + }; + } + function onCreated(confirmOrderResponse, actions) { + captureData = new FormData(); + captureData.append('orderID', confirmOrderResponse.id); + return fetch('[{$sSelfLink|cat:"cl=order&fnc=captureGooglePayOrder&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken|cat:"&sDeliveryAddressMD5="|cat:$oView->getDeliveryAddressMD5()}]', { + method: 'post', + body: captureData }).then(function(res) { + return res.json(); + }).then(function(data) { + console.log('-----DATA------') + console.log(data) + console.log('-----DATA END------') + var errorDetail = Array.isArray(data.details) && data.details[0]; + var goNext = Array.isArray(data.location) && data.location[0]; + + window.location.href = '[{$sSelfLink}]' + goNext; + console.log(data) + if (data.status === "ERROR") { + location.reload(); + } else if (data.id && data.status === "APPROVED") { + // location.replace(`${sSelfLink}cl=order&fnc=execute`); + } + }); + } + await onApprove(confirmOrderResponse, null); // Assuming 'actions' is not needed or can be null + await onCreated(confirmOrderResponse, null); // Assuming 'actions' is not needed or can be null + + /*** Capture the Order ****/ //const captureResponse = await fetch(`/orders/${id}/capture`, { // method: "POST", //}).then((res) => res.json()); return { transactionState: "SUCCESS" }; - + } else { return { transactionState: "ERROR" }; } - + } catch (err) { return { transactionState: "ERROR", diff --git a/views/smarty/frontend/google_pay.tpl b/views/smarty/frontend/google_pay.tpl index 94f9ba77..3371f2c3 100644 --- a/views/smarty/frontend/google_pay.tpl +++ b/views/smarty/frontend/google_pay.tpl @@ -1,8 +1,6 @@
- [{include file="modules/osc/paypal/select_payment.tpl"}] + getCheckedPaymentId() == $paymentmethod->oxpayments__oxid->value}]checked[{/if}]> -
- [{include file="modules/osc/paypal/googlepay.tpl" buttonId=$sPaymentID buttonClass="paypal-button-wrapper large"}]
From b7aad288424c88d6db4e9c955677c44d624deb44 Mon Sep 17 00:00:00 2001 From: Danny Date: Thu, 18 Apr 2024 16:21:58 +0200 Subject: [PATCH 097/265] WIP: configuration for deliveryadress from googlepay --- metadata.php | 6 +++++ .../Admin/PayPalConfigController.php | 4 ++- src/Core/Config.php | 5 ++++ src/Service/ModuleSettings.php | 4 +++ views/de/admin_translations.php | 3 +++ views/en/admin_translations.php | 3 +++ views/smarty/admin/oscpaypalconfig.tpl | 27 +++++++++++++++++++ views/smarty/frontend/blocks/googlepay.tpl | 5 +++- 8 files changed, 55 insertions(+), 2 deletions(-) diff --git a/metadata.php b/metadata.php index 7d145fcb..495f4cc8 100755 --- a/metadata.php +++ b/metadata.php @@ -546,5 +546,11 @@ 'value' => true, 'group' => null ], + [ + 'name' => 'oscPayPalUseGooglePayAddress', + 'type' => 'bool', + 'value' => false, + 'group' => null + ], ], ]; diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index 2b1c0644..050d57f2 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -284,7 +284,9 @@ protected function handleSpecialFields(array $conf): array if (!isset($conf['oscPayPalSetVaulting'])) { $conf['oscPayPalSetVaulting'] = false; } - + if (!isset($conf['oscPayPalUseGooglePayAddress'])) { + $conf['oscPayPalUseGooglePayAddress'] = false; + } return $conf; } diff --git a/src/Core/Config.php b/src/Core/Config.php index 330a9f6a..7585aced 100755 --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -441,6 +441,11 @@ public function getIsVaultingActive(): bool return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); } + public function getIsGooglePayDeliveryAdressActive(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->getIsGooglePayDeliveryAddressActive(); + } + public function isLogLevel(string $level): bool { $possiblePayPalLevels = [ diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 008b068f..87862d97 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -574,6 +574,10 @@ public function getIsVaultingActive(): bool { return (bool)$this->getSettingValue('oscPayPalSetVaulting'); } + public function getIsGooglePayDeliveryAddressActive(): bool + { + return (bool)$this->getSettingValue('oscPayPalUseGooglePayAddress'); + } /** * @return mixed diff --git a/views/de/admin_translations.php b/views/de/admin_translations.php index 3c052681..1faf861b 100755 --- a/views/de/admin_translations.php +++ b/views/de/admin_translations.php @@ -275,6 +275,9 @@ 'HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING' => 'Wiederholungskäufe leicht gemacht: Mit PayPal können Sie die bevorzugten Zahlarten Ihrer Kund:innen sicher speichern und so eine schnelle und einfache Kaufabwicklung ermöglichen. Mit ihren gespeicherten Zahlungsdaten können Kund:innen mit nur wenigen Klicks Wiederholungskäufe tätigen. Dies kann für Sie eine höhere Checkout-Conversion bedeuten.', + 'OSC_PAYPAL_GOOGLEPAY_TITLE' => 'Google Pay Adresse', + 'OSC_PAYPAL_GOOGLEPAY_ADDRESS_ACTIVATE' => 'Speicherung der Adresse aktivieren', + 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Übernahme der Lieferadresse von GooglePay', 'OSC_PAYPAL_INSTALLPROCESS_FAILED' => 'Da das Modul nicht korrekt per Composer installiert ist, sind Fehler bei der (De-)Aktivierung des Moduls aufgetreten. Bitte installieren Sie das Modul via Composer frisch und wiederholen den Vorgang.', ]; diff --git a/views/en/admin_translations.php b/views/en/admin_translations.php index d5fdfd46..8ff42850 100755 --- a/views/en/admin_translations.php +++ b/views/en/admin_translations.php @@ -276,6 +276,9 @@ 'HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING' => 'Repeat purchases made easy: With PayPal you can securely store your customers preferred payment methods, making it quick and easy Enable purchase processing. With their saved payment details, customers can make repeat purchases with just a few clicks. This can be for you mean higher checkout conversion.', + 'OSC_PAYPAL_GOOGLEPAY_TITLE' => 'Google Pay address', + 'OSC_PAYPAL_GOOGLEPAY_ADDRESS_ACTIVATE' => 'Google Pay address active', + 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Takeover delivery address from googlepay', 'OSC_PAYPAL_INSTALLPROCESS_FAILED' => 'Because the module was not installed correctly via Composer, errors occurred during the (de)activation of the module. Please reinstall the module via composer and repeat the process.', ]; diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl index 1713b29d..2c8fbf11 100755 --- a/views/smarty/admin/oscpaypalconfig.tpl +++ b/views/smarty/admin/oscpaypalconfig.tpl @@ -536,6 +536,33 @@
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+ [{oxmultilang ident="HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE"}] +
+
+
+
+
+
+
diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index e896376c..5e8a84ed 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -1,6 +1,9 @@ [{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] [{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] +[{assign var="oConfig" value=$oViewConf->getConfig()}] +[{assign var="bGooglePayDelivery" value=$oConfig->getConfigParam('oscPayPalUseGooglePayAddress')}] + +[{oxscript include="https://pay.google.com/gp/p/js/pay.js" }] [{oxscript add=$smarty.capture.detailsGooglePayScript}] - From 226b02e7c5d5c67f24f079e29fe14324a8b0f3af Mon Sep 17 00:00:00 2001 From: Danny Date: Mon, 22 Apr 2024 08:27:37 +0200 Subject: [PATCH 099/265] WIP: testing response --- src/Controller/ProxyController.php | 52 ++++++++++++++++-------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index d0b119c3..0b328b6b 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -237,32 +237,36 @@ public function createGooglepayOrder() /** @var array $userInvoiceAddress */ $userInvoiceAddress = $user->getInvoiceAddress(); // add PayPal-Address as Delivery-Address - - $response->purchase_units[0]->shipping->address = $shippingAddress; - $response->purchase_units[0]->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; - $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); - if ($deliveryAddress['oxaddress__oxfname'] !== '' && $deliveryAddress['oxaddress__oxstreet'] !== '') { - try { - $user->changeUserData( - $user->oxuser__oxusername->value, - '', - '', - $userInvoiceAddress, - $deliveryAddress - ); - - // use a deliveryaddress in oxid-checkout - Registry::getSession()->setVariable('blshowshipaddress', false); - - $this->setPayPalPaymentMethod(); - } catch (StandardException $exception) { - Registry::getUtilsView()->addErrorToDisplay($exception); - $response->status = 'ERROR'; - PayPalSession::unsetPayPalOrderId(); - Registry::getSession()->getBasket()->setPayment(null); + if ($response !== null) { + if (!empty($response->purchase_units[0]->shipping)) { + $response->purchase_units[0]->shipping; + + $response->purchase_units[0]->shipping->address = $shippingAddress; + $response->purchase_units[0]->shipping->name->full_name = $data['shippingAddress']['name'] ?? ''; + $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); + if ($deliveryAddress['oxaddress__oxfname'] !== '' && $deliveryAddress['oxaddress__oxstreet'] !== '') { + try { + $user->changeUserData( + $user->oxuser__oxusername->value, + '', + '', + $userInvoiceAddress, + $deliveryAddress + ); + + // use a deliveryaddress in oxid-checkout + Registry::getSession()->setVariable('blshowshipaddress', false); + + $this->setPayPalPaymentMethod(); + } catch (StandardException $exception) { + Registry::getUtilsView()->addErrorToDisplay($exception); + $response->status = 'ERROR'; + PayPalSession::unsetPayPalOrderId(); + Registry::getSession()->getBasket()->setPayment(null); + } + } } } - } elseif ($nonGuestAccountDetected && !$isLoggedIn) { // PPExpress is actual no possible so we switch to PP-Standard $this->setPayPalPaymentMethod(PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID); From 4c25d6984a4fb4c9a79d1ca76dcb168048baa0e3 Mon Sep 17 00:00:00 2001 From: Danny Date: Mon, 22 Apr 2024 11:23:56 +0200 Subject: [PATCH 100/265] WIP: adding googlepay to configuration-view, adding setting --- metadata.php | 12 +++++++++++ src/Core/Config.php | 8 +++++++ src/Core/Onboarding/Onboarding.php | 10 ++++++++- src/Service/ModuleSettings.php | 29 +++++++++++++++++++++++++- views/de/admin_translations.php | 1 + views/en/admin_translations.php | 1 + views/smarty/admin/oscpaypalconfig.tpl | 5 +++++ views/smarty/frontend/google_pay.tpl | 14 +++++++------ 8 files changed, 72 insertions(+), 8 deletions(-) diff --git a/metadata.php b/metadata.php index 495f4cc8..8916b8ef 100755 --- a/metadata.php +++ b/metadata.php @@ -485,6 +485,12 @@ 'value' => false, 'group' => null ], + [ + 'name' => 'oscPayPalGooglePayEligibility', + 'type' => 'bool', + 'value' => false, + 'group' => null + ], [ 'name' => 'oscPayPalSandboxAcdcEligibility', 'type' => 'bool', @@ -503,6 +509,12 @@ 'value' => false, 'group' => null ], + [ + 'name' => 'oscPayPalSandboxGooglePayEligibility', + 'type' => 'bool', + 'value' => false, + 'group' => null + ], [ 'name' => 'oscPayPalSCAContingency', 'type' => 'select', diff --git a/src/Core/Config.php b/src/Core/Config.php index 7585aced..e88375ae 100755 --- a/src/Core/Config.php +++ b/src/Core/Config.php @@ -128,6 +128,14 @@ public function isLiveVaultingEligibility(): bool { return $this->getServiceFromContainer(ModuleSettings::class)->isLiveVaultingEligibility(); } + public function isLiveGooglePayEligibility(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isLiveGooglePayEligibility(); + } + public function isSandboxGooglePayEligibility(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isSandboxGooglePayEligibility(); + } public function isSandboxAcdcEligibility(): bool { diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index d8314d40..17a8d48b 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -171,6 +171,7 @@ public function saveEligibility(array $merchantInformations): array $isAcdcEligibility = false; $isVaultingEligibility = false; $isVaultingCapability = false; + $isGooglePayCapability = false; foreach ($merchantInformations['capabilities'] as $capability) { if ( @@ -178,7 +179,12 @@ public function saveEligibility(array $merchantInformations): array $capability['status'] === 'ACTIVE' ) { $isVaultingCapability = true; - break; + } + if ( + $capability['name'] === 'GOOGLE_PAY' && + $capability['status'] === 'ACTIVE' + ) { + $isGooglePayCapability = true; } } @@ -208,11 +214,13 @@ public function saveEligibility(array $merchantInformations): array $moduleSettings->savePuiEligibility($isPuiEligibility); $moduleSettings->saveAcdcEligibility($isAcdcEligibility); $moduleSettings->saveVaultingEligibility($isVaultingEligibility); + $moduleSettings->saveGooglePayEligibility($isGooglePayCapability); return [ 'acdc' => $isAcdcEligibility, 'pui' => $isPuiEligibility, 'vaulting' => $isVaultingEligibility, + 'googlepay' => $isGooglePayCapability, ]; } } diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 87862d97..caf8abd1 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -349,7 +349,16 @@ public function isLiveVaultingEligibility(): bool { return (bool)$this->getSettingValue('oscPayPalVaultingEligibility'); } - + public function isLiveGooglePayEligibility(): bool + { + return (bool)$this->getSettingValue('oscPayPalGooglePayEligibility'); + } + public function isGooglePayEligibility(): bool + { + return $this->isSandbox()? + $this->isSandBoxVaultingEligibility() : + $this->isLiveVaultingEligibility(); + } public function isSandboxAcdcEligibility(): bool { return (bool)$this->getSettingValue('oscPayPalSandboxAcdcEligibility'); @@ -364,6 +373,10 @@ public function isSandboxVaultingEligibility(): bool { return (bool)$this->getSettingValue('oscPayPalSandboxVaultingEligibility'); } + public function isSandboxGooglePayEligibility(): bool + { + return (bool)$this->getSettingValue('oscPayPalSandboxGooglePayEligibility'); + } public function getIsVaultingActive(): bool { @@ -473,6 +486,18 @@ public function saveWebhookId(string $webhookId): void } } + public function saveActivePayments(array $activePayments): void + { + $this->save('oscPayPalActivePayments', $activePayments); + } + public function saveGooglePayEligibility(bool $isGooglePayEligibility): void + { + if ($this->isSandbox()) { + $this->save('oscPayPalSandboxGooglePayEligibility', $isGooglePayEligibility); + } else { + $this->save('oscPayPalGooglePayEligibility', $isGooglePayEligibility); + } + } /** * add details controller to requireSession */ @@ -591,4 +616,6 @@ private function isAdmin(): bool { return isAdmin(); } + + } diff --git a/views/de/admin_translations.php b/views/de/admin_translations.php index 1faf861b..cc3281f6 100755 --- a/views/de/admin_translations.php +++ b/views/de/admin_translations.php @@ -72,6 +72,7 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY' => 'GooglePay', 'OSC_PAYPAL_LOCALISATIONS' => 'Spracheinstellungen', 'OSC_PAYPAL_LOCALES' => 'regionale Spracheinstellungen', diff --git a/views/en/admin_translations.php b/views/en/admin_translations.php index 8ff42850..2e2125cd 100755 --- a/views/en/admin_translations.php +++ b/views/en/admin_translations.php @@ -71,6 +71,7 @@ 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', 'OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING' => 'Vaulting', + 'OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY' => 'GooglePay', 'OSC_PAYPAL_LOCALISATIONS' => 'Locals', 'OSC_PAYPAL_LOCALES' => 'regional language settings', diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl index 70f7e8d5..b37bb2f7 100755 --- a/views/smarty/admin/oscpaypalconfig.tpl +++ b/views/smarty/admin/oscpaypalconfig.tpl @@ -108,6 +108,8 @@ [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC" suffix="COLON"}] [{if $config->isLiveAcdcEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}] [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK"}][{/if}]
[{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING" suffix="COLON"}] [{if $config->isLiveVaultingEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] +
+ [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY" suffix="COLON"}] [{if $config->isLiveGooglePayEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] @@ -163,6 +165,9 @@ [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC" suffix="COLON"}] [{if $config->isSandboxAcdcEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}] [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_ACDC_FALLBACK"}][{/if}]
[{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_VAULTING" suffix="COLON"}] [{if $config->isSandboxVaultingEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] +
+ [{oxmultilang ident="OSC_PAYPAL_SPECIAL_PAYMENTS_GOOGLEPAY" suffix="COLON"}] [{if $config->isSandboxGooglePayEligibility()}][{oxmultilang ident="GENERAL_YES"}][{else}][{oxmultilang ident="GENERAL_NO"}][{/if}] + diff --git a/views/smarty/frontend/google_pay.tpl b/views/smarty/frontend/google_pay.tpl index 3371f2c3..2558266c 100644 --- a/views/smarty/frontend/google_pay.tpl +++ b/views/smarty/frontend/google_pay.tpl @@ -1,6 +1,8 @@ -
-
- getCheckedPaymentId() == $paymentmethod->oxpayments__oxid->value}]checked[{/if}]> - -
-
+
+
+
+ getCheckedPaymentId() == $paymentmethod->oxpayments__oxid->value}]checked[{/if}]> + +
+
+
From 19035148aaad32b8354f5c05a1390b1ed515dfa1 Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 24 Apr 2024 09:25:56 +0200 Subject: [PATCH 101/265] WIP: added if-statements for console.log --- views/smarty/frontend/blocks/googlepay.tpl | 31 ++++++++++++++++------ 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 0dffd848..ef05630f 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -95,13 +95,17 @@ } async function onGooglePayLoaded() { - console.log('onGooglePayLoaded triggered'); const paymentsClient = getGooglePaymentsClient(); const { allowedPaymentMethods } = await getGooglePayConfig(); paymentsClient .isReadyToPay(getGoogleIsReadyToPayRequest(allowedPaymentMethods)) .then(function (response) { + [{if $config->isSandbox() }] + console.log('getGoogleIsReadyToPayResponse debug') + console.log(response) + console.log('getGoogleIsReadyToPayResponse debugend') + [{/if}] if (response.result) { addGooglePayButton(); } @@ -143,6 +147,11 @@ } const paymentsClient = getGooglePaymentsClient(); + [{if $config->isSandbox() }] + console.log('paymentDataRequest debug') + console.log(paymentDataRequest) + console.log('paymentDataRequest debugend') + [{/if}] paymentsClient.loadPaymentData(paymentDataRequest) .then(function() { // location.replace("[{$sSelfLink|cat:"cl=order&fnc=execute"}]"); @@ -167,13 +176,17 @@ orderId: id, paymentMethodData: paymentData.paymentMethodData, }); - console.log('--------') + [{if $config->isSandbox() }] + console.log('confirmOrderResponse debug') console.log(confirmOrderResponse) - console.log('--------') + console.log('confirmOrderResponse debugend') + [{/if}] if (confirmOrderResponse.status === "APPROVED") { - console.log('approved'); - console.log(paymentData); - + [{if $config->isSandbox() }] + console.log('approved paymentData debug') + console.log(paymentData) + console.log('approved paymentData debugend') + [{/if}] function onApprove(confirmOrderResponse, actions) { // Create a new form dynamically var form = document.createElement("form"); @@ -222,9 +235,11 @@ body: captureData }).then(function(res) { return res.json(); }).then(function(data) { - console.log('-----DATA------') + [{if $config->isSandbox() }] + console.log('onCreated captureData debug') console.log(data) - console.log('-----DATA END------') + console.log('onCreated captureData debugend') + [{/if}] var errorDetail = Array.isArray(data.details) && data.details[0]; var goNext = Array.isArray(data.location) && data.location[0]; From e67307bdf26b0e5023e529d9d5f57bc3582a4d33 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 25 Apr 2024 13:59:40 +0200 Subject: [PATCH 102/265] use smarty parent instead of own tpl (the content is the same) --- metadata.php | 1 - views/blocks/page/checkout/select_payment.tpl | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/metadata.php b/metadata.php index 8916b8ef..6e293842 100755 --- a/metadata.php +++ b/metadata.php @@ -120,7 +120,6 @@ 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', - 'modules/osc/paypal/google_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/google_pay.tpl', 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', diff --git a/views/blocks/page/checkout/select_payment.tpl b/views/blocks/page/checkout/select_payment.tpl index 2cf36427..a2c5c446 100644 --- a/views/blocks/page/checkout/select_payment.tpl +++ b/views/blocks/page/checkout/select_payment.tpl @@ -8,7 +8,8 @@ [{elseif $sPaymentID == "oscpaypal_googlepay"}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] - [{include file="modules/osc/paypal/google_pay.tpl" sPaymentID=$sPaymentID}] + [{* we can use the standard-block, but only with a valid config and a non existing pp-express-session *}] + [{$smarty.block.parent}] [{/if}] [{else}] [{$smarty.block.parent}] From 5319169b2c3a800ef6a8c0639d42e2f20dc45f38 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 25 Apr 2024 14:00:48 +0200 Subject: [PATCH 103/265] Adjusted indentations to make the code easier to read --- views/smarty/frontend/blocks/googlepay.tpl | 524 +++++++++++---------- 1 file changed, 266 insertions(+), 258 deletions(-) diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index ef05630f..37b99b04 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -1,6 +1,6 @@ [{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] [{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] -[{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] +[{assign var="oPPconfig" value=$oViewConf->getPayPalCheckoutConfig()}] [{assign var="oConfig" value=$oViewConf->getConfig()}] [{assign var="bGooglePayDelivery" value=$oConfig->getConfigParam('oscPayPalUseGooglePayAddress')}] - -[{oxscript include="https://pay.google.com/gp/p/js/pay.js" }] +[{oxscript include="https://pay.google.com/gp/p/js/pay.js"}] [{oxscript add=$smarty.capture.detailsGooglePayScript}] From ad56f82c25aeabafe7b3058ffe5a85e3c5f9cb26 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 25 Apr 2024 15:47:10 +0200 Subject: [PATCH 104/265] add more Sandbox-Flags --- views/smarty/frontend/blocks/googlepay.tpl | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 37b99b04..dac053f1 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -9,7 +9,7 @@ } [{capture name="detailsGooglePayScript"}] - [{if false}] \ No newline at end of file + +[{/if}] \ No newline at end of file diff --git a/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl b/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl index 795f694a..65677999 100644 --- a/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl +++ b/views/tpl/wave/page/checkout/shipping_and_payment_paypal.tpl @@ -43,7 +43,7 @@
[{assign var="payment" value=$oView->getPayment()}] [{$payment->oxpayments__oxdesc->value}] - [{if $oscpaypal_payment_saveable}] + [{if $oscpaypal_isVaultingPossible}]

@@ -55,6 +55,7 @@
+[{if $oscpaypal_isVaultingPossible}] \ No newline at end of file + +[{/if}] \ No newline at end of file From 76492eb25e2860bb09013ffb1826630c3c56a8ef Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 24 May 2024 11:19:00 +0200 Subject: [PATCH 125/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fee4c6a2..36d12037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix admin block parent call, thanks to Alpha-Sys - Fix Errorlog-Message "Duplicate entry ..." + fix Update send PUI-Bankdata via Webhook - Fix PayPalExpress Reauth is necessary if the cart amount (total is greater than before) has changed during the checkout process +- Fix, don't show vaulting-Boxes if it is deactivated in Backend ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From b87b088b34856fc8b4c52e857e4a73399b6d968a Mon Sep 17 00:00:00 2001 From: Danny Date: Thu, 6 Jun 2024 10:01:56 +0200 Subject: [PATCH 126/265] PSPAYPAL-774: added if-statement and method from ModuleSettings.php --- src/Core/ViewConfig.php | 5 +++++ views/blocks/page/account/inc/account_menu.tpl | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 20c7f6eb..38f12ab8 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -595,4 +595,9 @@ public function getGeneratePaymentTokenLink() return $url . $params . '&token='; } + + public function isAcdcEligibility(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isAcdcEligibility(); + } } diff --git a/views/blocks/page/account/inc/account_menu.tpl b/views/blocks/page/account/inc/account_menu.tpl index a99dd822..0356d6d5 100644 --- a/views/blocks/page/account/inc/account_menu.tpl +++ b/views/blocks/page/account/inc/account_menu.tpl @@ -2,8 +2,10 @@ - + [{if $oViewConf->isAcdcEligibility() }] + + [{/if}] [{/if}] -[{$smarty.block.parent}] \ No newline at end of file +[{$smarty.block.parent}] From 09639aa8ef4f5edc4778339fe55fca577d6c766a Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 5 Jun 2024 14:44:33 +0200 Subject: [PATCH 127/265] PSPAYPAL-773: check for vaulting, change setting if vaulting is not active. --- .../Admin/PayPalConfigController.php | 5 +++-- views/smarty/admin/oscpaypalconfig.tpl | 22 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index 062dcf56..2badc1a0 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -172,7 +172,7 @@ public function save() $confArr = $this->handleSpecialFields($confArr); $this->saveConfig($confArr); - $this->checkEligibility(); + $this->checkEligibility($confArr); parent::save(); } @@ -191,9 +191,10 @@ protected function saveConfig(array $conf): void /** * check Eligibility if config would be changed * + * @param $confArr array * @throws OnboardingException */ - protected function checkEligibility(): void + protected function checkEligibility($confArr): void { $config = new Config(); /** skip check if no client ID provided */ diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl index 73ec4250..4ea997c6 100755 --- a/views/smarty/admin/oscpaypalconfig.tpl +++ b/views/smarty/admin/oscpaypalconfig.tpl @@ -506,17 +506,21 @@
-
-
-
- +
+
+
+ +
+ [{oxmultilang ident="HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING"}]
- [{oxmultilang ident="HELP_OSC_PAYPAL_VAULTING_ACTIVATE_VAULTING"}]
-
From aaa13c90b58e9f0954e813f5feb6e30b5cbae64a Mon Sep 17 00:00:00 2001 From: markusmichalski-fc Date: Tue, 28 May 2024 12:41:56 +0200 Subject: [PATCH 128/265] 7656: Fixed incompatibility with Klarna plugin --- src/Model/Order.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Model/Order.php b/src/Model/Order.php index cd74a4c7..3a8263a5 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -266,9 +266,6 @@ protected function afterOrderCleanUp(Basket $basket, User $user): void // phpcs:ignore PSR2.Methods.MethodDeclaration.Underscore protected function executePayment(Basket $basket, $userpayment) { - //order number needs to be set before the payment is requested - $this->setOrderNumber(); - $paymentService = $this->getServiceFromContainer(PaymentService::class); $sessionPaymentId = (string) $paymentService->getSessionPaymentId(); From 451207f35588bedcb00b914f7e40e0402df06a54 Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 24 Apr 2024 08:11:43 +0200 Subject: [PATCH 129/265] WIP: added applepay templates, some config --- metadata.php | 3 + src/Controller/ProxyController.php | 9 +- src/Core/PayPalDefinitions.php | 23 ++ src/Core/ViewConfig.php | 2 +- .../checkout_order_btn_submit_bottom.tpl | 12 + views/blocks/page/checkout/select_payment.tpl | 5 + views/smarty/frontend/apple_pay.tpl | 8 + views/smarty/frontend/blocks/applepay.tpl | 390 ++++++++++++++++++ 8 files changed, 447 insertions(+), 5 deletions(-) create mode 100644 views/smarty/frontend/apple_pay.tpl create mode 100644 views/smarty/frontend/blocks/applepay.tpl diff --git a/metadata.php b/metadata.php index 3b58ad2c..18df58f5 100755 --- a/metadata.php +++ b/metadata.php @@ -120,6 +120,7 @@ 'modules/osc/paypal/pui_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/pui.tpl', 'modules/osc/paypal/pui_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/pui.tpl', 'modules/osc/paypal/pui_fraudnet.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/pui_fraudnet.tpl', + 'modules/osc/paypal/apple_pay.tpl' => 'osc/paypal/views/tpl/shared/page/checkout/apple_pay.tpl', 'modules/osc/paypal/shipping_and_payment_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_wave.tpl' => 'osc/paypal/views/tpl/wave/page/checkout/shipping_and_payment.tpl', 'modules/osc/paypal/shipping_and_payment_paypal_flow.tpl' => 'osc/paypal/views/tpl/flow/page/checkout/shipping_and_payment_paypal.tpl', @@ -147,6 +148,8 @@ // PSPAYPAL-491 Installment banners 'modules/osc/paypal/installment_banners.tpl' => 'osc/paypal/views/tpl/shared/installment_banners.tpl', + 'modules/osc/paypal/applepay.tpl' => 'osc/paypal/views/tpl/shared/applepay.tpl', + // PSPAYPAL-685 Installment banners 'modules/osc/paypal/googlepay.tpl' => 'osc/paypal/views/tpl/shared/googlepay.tpl', diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index a47d533c..7eb8e6dd 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -19,6 +19,7 @@ use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Price; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Api\VaultingService; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface; use OxidSolutionCatalysts\PayPal\Module; @@ -33,12 +34,12 @@ use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiOrder; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\PurchaseUnitRequest; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Payer; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\PurchaseUnitRequest; +use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Phone as ApiModelPhone; use OxidSolutionCatalysts\PayPalApi\Model\Orders\PhoneWithType; use OxidSolutionCatalysts\PayPalApi\Model\Orders\ShippingDetail; @@ -55,7 +56,7 @@ public function createOrder() { if (PayPalSession::isPayPalExpressOrderActive()) { //TODO: improve - $this->outputJson(['ERROR' => 'PayPal session already started.']); + // $this->outputJson(['ERROR' => 'PayPal session already started.']); } $config = Registry::getConfig(); diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index 01f5b82e..81ad2b0f 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -20,6 +20,7 @@ final class PayPalDefinitions public const GIROPAY_PAYPAL_PAYMENT_ID = 'oscpaypal_giropay'; public const SEPA_PAYPAL_PAYMENT_ID = 'oscpaypal_sepa'; public const CCALTERNATIVE_PAYPAL_PAYMENT_ID = 'oscpaypal_cc_alternative'; + public const APPLEPAY_PAYPAL_PAYMENT_ID = 'oscpaypal_applepay'; public const GOOGLEPAY_PAYPAL_PAYMENT_ID = 'oscpaypal_googlepay'; //vaulting @@ -71,6 +72,28 @@ final class PayPalDefinitions 'defaulton' => true ], //GooglePay + self::APPLEPAY_PAYPAL_PAYMENT_ID => [ + 'descriptions' => [ + 'de' => [ + 'desc' => 'ApplePay', + 'longdesc' => '', + 'longdesc_beta' => 'Bezahlen Sie bequem mit ApplePay. Starten Sie direkt von der Detailsseite oder im Warenkorb.' + ], + 'en' => [ + 'desc' => 'ApplePay', + 'longdesc' => '', + 'longdesc_beta' => 'Pay conveniently with ApplePay. Start directly from the details page or in the shopping cart.' + ] + ], + 'countries' => [], + 'currencies' => ['AUD', 'BRL', 'CAD', 'CNY', 'CZK', 'DKK', 'EUR', 'HKD', 'HUF', 'ILS', 'JPY', 'MYR', 'MXN', 'TWD', 'NZD', 'NOK', 'PHP', 'PLN', 'GBP', 'RUB', 'SGD', 'SEK', 'CHF', 'THB', 'USD'], + 'uapmpaymentsource' => 'applepay', + 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, + 'onlybrutto' => false, + 'buttonpayment' => false, + 'defaulton' => true + ], + //GooglePay self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ 'de' => [ diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 38f12ab8..c77b2637 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -180,7 +180,7 @@ public function getPayPalJsSdkUrl(): string if ($this->isPayPalBannerActive()) { $params['components'] .= ',messages'; } - + $params['components'] .= ',applepay'; if ($moduleSettings->showPayPalPayLaterButton()) { $params['enable-funding'] = 'paylater'; } diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index 62e3ac4a..7e4f74d8 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -9,6 +9,18 @@ [{include file="modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl"}] [{/if}] [{/if}] +[{if "oscpaypal_applepay" == $payment->getId()}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{else}] + [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{/if}] +
+ + [{else}] + [{$smarty.block.parent}] +[{/if}] + [{if "oscpaypal_googlepay" == $payment->getId()}] [{if $oViewConf->isFlowCompatibleTheme()}] diff --git a/views/blocks/page/checkout/select_payment.tpl b/views/blocks/page/checkout/select_payment.tpl index a2c5c446..d5099524 100644 --- a/views/blocks/page/checkout/select_payment.tpl +++ b/views/blocks/page/checkout/select_payment.tpl @@ -5,6 +5,11 @@ [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] [{include file="modules/osc/paypal/sepa_cc_alternative.tpl" sPaymentID=$sPaymentID}] [{/if}] +[{elseif $sPaymentID == "oscpaypal_applepay"}] + [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] + [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] + [{include file="modules/osc/paypal/apple_pay.tpl" sPaymentID=$sPaymentID}] + [{/if}] [{elseif $sPaymentID == "oscpaypal_googlepay"}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] [{if $config->isActive() && !$oViewConf->isPayPalExpressSessionActive()}] diff --git a/views/smarty/frontend/apple_pay.tpl b/views/smarty/frontend/apple_pay.tpl new file mode 100644 index 00000000..2558266c --- /dev/null +++ b/views/smarty/frontend/apple_pay.tpl @@ -0,0 +1,8 @@ +
+
+
+ getCheckedPaymentId() == $paymentmethod->oxpayments__oxid->value}]checked[{/if}]> + +
+
+
diff --git a/views/smarty/frontend/blocks/applepay.tpl b/views/smarty/frontend/blocks/applepay.tpl new file mode 100644 index 00000000..28db3082 --- /dev/null +++ b/views/smarty/frontend/blocks/applepay.tpl @@ -0,0 +1,390 @@ +[{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] +[{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] +[{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] +[{assign var="oConfig" value=$oViewConf->getConfig()}] +[{assign var="bApplePayDelivery" value=$oConfig->getConfigParam('oscPayPalUseApplePayAddress')}] + +[{if $phpstorm}][{/if}] +[{oxscript include="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js" }] +[{oxscript add=$smarty.capture.detailsApplePayScriptPaymentPage}] From 98dfc1f0f167fc5913ca4c92d3098c1803f0141b Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 28 May 2024 11:41:11 +0200 Subject: [PATCH 135/265] PSPAYPAL-684_ApplePay: changed tpl to elseif --- .../checkout_order_btn_submit_bottom.tpl | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index a21da59f..793ecd7c 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -9,19 +9,6 @@ [{include file="modules/osc/paypal/checkout_order_btn_submit_bottom_wave.tpl"}] [{/if}] [{/if}] -[{if "oscpaypal_apple_pay" == $payment->getId()}] - [{if $oViewConf->isFlowCompatibleTheme()}] - [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] - [{else}] - [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] - [{/if}] -
- - [{else}] - [{$smarty.block.parent}] -[{/if}] - - [{if "oscpaypal_googlepay" == $payment->getId()}] [{if $oViewConf->isFlowCompatibleTheme()}] [{include file="modules/osc/paypal/googlepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] @@ -30,6 +17,17 @@ [{/if}]
+[{elseif "oscpaypal_apple_pay" == $payment->getId()}] + [{if $oViewConf->isFlowCompatibleTheme()}] + [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{else}] + [{include file="modules/osc/paypal/applepay.tpl" buttonId=$payment->getId() buttonClass="paypal-button-wrapper large"}] + [{/if}] +
[{else}] [{$smarty.block.parent}] [{/if}] + + + + From 81440121318f808dda4780b540b28b75a4694e3d Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 10:27:56 +0200 Subject: [PATCH 136/265] code-style --- src/Controller/OrderController.php | 8 +++----- src/Controller/ProxyController.php | 17 ++++++++++------- src/Core/OrderRequestFactory.php | 5 +++-- src/Model/PaymentGateway.php | 2 +- src/Service/Payment.php | 2 -- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index d7906b80..137fa6fb 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -401,12 +401,11 @@ public function createApplePayOrder(): void $_POST['sDeliveryAddressMD5'] = $this->getDeliveryAddressMD5(); $status = $this->execute(); - } catch (Exception $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); - $this->outputJson(['error' => 'failed to execute shop order'.$exception->getMessage()]); + $this->outputJson(['error' => 'failed to execute shop order' . $exception->getMessage()]); return; } @@ -418,7 +417,7 @@ public function createApplePayOrder(): void return; } - if (!$status ) { + if (!$status) { $response = ['error' => 'unexpected order status ' . $status]; $paymentService->removeTemporaryOrder(); } else { @@ -449,11 +448,10 @@ public function captureApplePayOrder() '', ); } catch (ApiException $exception) { - $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); - throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR'.$exception->getMessage()); + throw oxNew(StandardException::class, 'OSC_PAYPAL_ORDEREXECUTION_ERROR' . $exception->getMessage()); } try { diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 7572978f..c82d8bfc 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -483,7 +483,8 @@ protected function getRequestedPayPalPaymentId( $defaultPayPalPaymentId; } - public function getPaymentRequestLines() { + public function getPaymentRequestLines() + { try { $basket = Registry::getSession()->getBasket(); @@ -545,7 +546,6 @@ public function createApplepayOrder() $shippingAddress->country_code = $shippingData['shippingContact']['countryCode'] ?? ''; if (PayPalSession::isPayPalExpressOrderActive()) { //TODO: improve - } $paymentId = Registry::getSession()->getVariable('paymentid'); @@ -585,7 +585,8 @@ public function createApplepayOrder() $response->payer = new Payer(); $response->payer->email_address = $data['email']; - $response->payer->phone->phone_number->national_number = $shippingData['shippingContact']['phoneNumber'] ?? ''; + $response->payer->phone->phone_number->national_number = + $shippingData['shippingContact']['phoneNumber'] ?? ''; $userRepository = $this->getServiceFromContainer(UserRepository::class); $paypalEmail = $data['email']; @@ -609,9 +610,13 @@ public function createApplepayOrder() // add PayPal-Address as Delivery-Address if (($response !== null) && !empty($response->purchase_units[0]->shipping)) { $response->purchase_units[0]->shipping->address = $shippingAddress; - $response->purchase_units[0]->shipping->name->full_name = $shippingData['shippingContact']['name'] ?? ''; + $response->purchase_units[0]->shipping->name->full_name = + $shippingData['shippingContact']['name'] ?? ''; $deliveryAddress = PayPalAddressResponseToOxidAddress::mapUserDeliveryAddress($response); - if ($deliveryAddress['oxaddress__oxfname'] !== '' && $deliveryAddress['oxaddress__oxstreet'] !== '') { + if ( + $deliveryAddress['oxaddress__oxfname'] !== '' + && $deliveryAddress['oxaddress__oxstreet'] !== '' + ) { try { $user->changeUserData( $user->oxuser__oxusername->value, @@ -645,6 +650,4 @@ public function createApplepayOrder() } $this->outputJson($response); } - - } diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 177970a1..f2fca39a 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -101,7 +101,7 @@ public function getRequest( $selectedVaultPaymentSourceIndex = Registry::getSession()->getVariable("selectedVaultPaymentSourceIndex"); $paymentId = Registry::getSession()->getVariable('paymentid'); if ($paymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { - $request->payment_source = $this->getApplePayPaymentSource($basket,'apple_pay'); + $request->payment_source = $this->getApplePayPaymentSource($basket, 'apple_pay'); } $paymentId = Registry::getSession()->getVariable('paymentid'); if ($paymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { @@ -177,7 +177,8 @@ public function getRequest( return $request; } - protected function getApplePayPaymentSource($basket, $requestName) { + protected function getApplePayPaymentSource($basket, $requestName) + { $user = $basket->getBasketUser(); diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index f9804175..fb2636f5 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -46,7 +46,7 @@ public function executePayment($amount, &$order) $success = parent::executePayment($amount, $order); } $paypalOrderId = ''; - if ($sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID ) { + if ($sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { $paypalOrderId = Registry::getRequest()->getRequestParameter('orderID'); } if ( diff --git a/src/Service/Payment.php b/src/Service/Payment.php index 5df7b528..c0e589dd 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -563,9 +563,7 @@ public function doExecuteUAPMPayment(EshopModelOrder $order, EshopModelBasket $b $uapmOrderId, PayPalDefinitions::getPaymentSourceRequestName($basket->getPaymentId()) ); - } catch (Exception $exception) { - PayPalSession::unsetPayPalOrderId(); $this->removeTemporaryOrder(); //TODO: do we need to log this? From 455974b7e75e45ddaf8f892e7d1fddc91fc82675 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 10:30:11 +0200 Subject: [PATCH 137/265] set Version Number --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36d12037..eeb03179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support -## [2.4.1] - 2024-??-?? +## [2.5.0] - 2024-??-?? ### FIX @@ -71,6 +71,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore - Introduce GooglePay-Payment +- Introduce ApplePay-Payment - use PayPal-Client v2.0.14 - add Default-Shippingcosts for PP-Express to prevent overcharge. From 2f9a818d149a1b88c40fcaabd0797cb3694cbe20 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 10:52:45 +0200 Subject: [PATCH 138/265] CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eeb03179..af8e8ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,7 +66,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix admin block parent call, thanks to Alpha-Sys - Fix Errorlog-Message "Duplicate entry ..." + fix Update send PUI-Bankdata via Webhook - Fix PayPalExpress Reauth is necessary if the cart amount (total is greater than before) has changed during the checkout process -- Fix, don't show vaulting-Boxes if it is deactivated in Backend +- Fix, don't show vaulting-Boxes if it is deactivated in Backend +- Fix, incompatibility with Klarna-Module ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From b5d84086d98f1f96003f3be1e1db9dc333c9bdec Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 10:55:08 +0200 Subject: [PATCH 139/265] CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af8e8ccf..b089f7c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,7 +67,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix Errorlog-Message "Duplicate entry ..." + fix Update send PUI-Bankdata via Webhook - Fix PayPalExpress Reauth is necessary if the cart amount (total is greater than before) has changed during the checkout process - Fix, don't show vaulting-Boxes if it is deactivated in Backend -- Fix, incompatibility with Klarna-Module +- [0007656](https://bugs.oxid-esales.com/view.php?id=7656): Fix incompatibility with Klarna-Module ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 601cbba6ce47142ca6b349292bb3f937d0d70ab2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 09:08:34 +0000 Subject: [PATCH 140/265] Update tag to v1.0.10 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 77e86d42..5b0c9c43 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v1.0.9 \ No newline at end of file +v1.0.10 \ No newline at end of file From 0e6ef16e5dcac5e22d728a7641aabddf7a33bc29 Mon Sep 17 00:00:00 2001 From: Danny Date: Wed, 5 Jun 2024 13:24:05 +0200 Subject: [PATCH 141/265] PSPAYPAL-775: Added method to verify if payment is allowed and display vaulting details if applicable --- src/Controller/PaymentController.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 7626ea0f..05af6b4d 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -56,9 +56,13 @@ public function render() ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { + $paymentList = $this->getPaymentList(); $vaultedPaymentSources = []; foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { + if (!$this->paymentTypeExists($paymentList, $paymentType)) { + continue; + } if ($paymentType === "card") { $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); $vaultedPaymentSources[$paymentType][] = $paymentSource["brand"] . " " . @@ -80,6 +84,28 @@ public function render() return parent::render(); } + /** + * @param $paymentList + * @param $paymentType + * @return bool + */ + protected function paymentTypeExists($paymentList, $paymentType): bool + { + if ($paymentType === 'paypal') { + $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID; + } else { + $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_'.$paymentType; + } + if ($paymentType === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_card') { + $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_acdc'; + } + foreach ($paymentList as $payment) { + if ($payment->getId() === $paymentType || $payment->getId() === "oscpaypal_" . $paymentType) { + return true; + } + } + return false; + } public function getPayPalPuiFraudnetCmId(): string { From a9f4563c4aa611a58b50c069e37f941221f57d12 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 12:15:16 +0200 Subject: [PATCH 142/265] optimize Vaulting-Check --- src/Controller/PaymentController.php | 17 +++++------------ src/Core/PayPalDefinitions.php | 20 ++++++++++++++++---- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 05af6b4d..72590131 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -56,11 +56,10 @@ public function render() ) { $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { - $paymentList = $this->getPaymentList(); $vaultedPaymentSources = []; foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { - if (!$this->paymentTypeExists($paymentList, $paymentType)) { + if (!$this->paymentTypeExists($paymentType)) { continue; } if ($paymentType === "card") { @@ -89,23 +88,17 @@ public function render() * @param $paymentType * @return bool */ - protected function paymentTypeExists($paymentList, $paymentType): bool + protected function paymentTypeExists($paymentType): bool { - if ($paymentType === 'paypal') { - $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID; - } else { - $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_'.$paymentType; - } - if ($paymentType === PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_card') { - $paymentType = PayPalDefinitions::STANDARD_PAYPAL_PAYMENT_ID.'_acdc'; - } + $paymentList = $this->getPaymentList(); foreach ($paymentList as $payment) { - if ($payment->getId() === $paymentType || $payment->getId() === "oscpaypal_" . $paymentType) { + if (PayPalDefinitions::isPayPalVaultingPossible($payment->getId(), $paymentType)) { return true; } } return false; } + public function getPayPalPuiFraudnetCmId(): string { diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index dcbeac71..c1e2490e 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -69,7 +69,8 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, - 'defaulton' => true + 'defaulton' => true, + 'vaultingtype' => 'paypal' ], //GooglePay self::APPLEPAY_PAYPAL_PAYMENT_ID => [ @@ -134,7 +135,8 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, - 'defaulton' => true + 'defaulton' => true, + 'vaultingtype' => 'paypal' ], //Express PayPal self::EXPRESS_PAYPAL_PAYMENT_ID => [ @@ -155,7 +157,8 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => true, - 'defaulton' => true + 'defaulton' => true, + 'vaultingtype' => 'paypal' ], self::PUI_PAYPAL_PAYMENT_ID => [ 'descriptions' => [ @@ -243,7 +246,8 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, - 'defaulton' => true + 'defaulton' => true, + 'vaultingtype' => 'card' ], // uAPM Bancontact 'oscpaypal_bancontact' => [ @@ -503,6 +507,14 @@ public static function isPayPalPayment(string $paymentId): bool return (isset(self::PAYPAL_DEFINTIONS[$paymentId])); } + public static function isPayPalVaultingPossible(string $paymentId, string $paypalPaymentType): bool + { + return ( + isset(self::PAYPAL_DEFINTIONS[$paymentId]['vaultingtype']) + && self::PAYPAL_DEFINTIONS[$paymentId]['vaultingtype'] === $paypalPaymentType + ); + } + /** * Check if payment is deprecated * From 52141a548c8d101c15ff1c5c8856cea493a8ffe0 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 12:17:22 +0200 Subject: [PATCH 143/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b089f7c6..1f5ca269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix PayPalExpress Reauth is necessary if the cart amount (total is greater than before) has changed during the checkout process - Fix, don't show vaulting-Boxes if it is deactivated in Backend - [0007656](https://bugs.oxid-esales.com/view.php?id=7656): Fix incompatibility with Klarna-Module +- better Vaulting-Check in PaymentController ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 95a7621ec2d5ea02772b0d3ee1a2851041faa18e Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 12:42:56 +0200 Subject: [PATCH 144/265] codestyle & CHANGELOG --- CHANGELOG.md | 1 + src/Controller/Admin/PayPalConfigController.php | 2 +- views/smarty/admin/oscpaypalconfig.tpl | 6 +----- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f5ca269..f811d038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fix, don't show vaulting-Boxes if it is deactivated in Backend - [0007656](https://bugs.oxid-esales.com/view.php?id=7656): Fix incompatibility with Klarna-Module - better Vaulting-Check in PaymentController +- disable Vaulting-Setting if Vaulting not possible ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index 2badc1a0..ae0f5a37 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -194,7 +194,7 @@ protected function saveConfig(array $conf): void * @param $confArr array * @throws OnboardingException */ - protected function checkEligibility($confArr): void + protected function checkEligibility(array $confArr): void { $config = new Config(); /** skip check if no client ID provided */ diff --git a/views/smarty/admin/oscpaypalconfig.tpl b/views/smarty/admin/oscpaypalconfig.tpl index c74a3f74..3594fdec 100755 --- a/views/smarty/admin/oscpaypalconfig.tpl +++ b/views/smarty/admin/oscpaypalconfig.tpl @@ -515,11 +515,7 @@
From 273f06a4a5797b8b59483a957f6f1aabbe808274 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 6 Jun 2024 12:43:21 +0200 Subject: [PATCH 145/265] fix wrong ModuleSettings --- src/Service/ModuleSettings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 212985f9..046f6f5d 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -364,8 +364,8 @@ public function isLiveGooglePayEligibility(): bool public function isGooglePayEligibility(): bool { return $this->isSandbox() ? - $this->isSandBoxVaultingEligibility() : - $this->isLiveVaultingEligibility(); + $this->isSandboxGooglePayEligibility() : + $this->isLiveGooglePayEligibility(); } public function isSandboxAcdcEligibility(): bool { From bea1ff44427c3e700a616ed0fe7d20a048d9f53d Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 11 Jun 2024 10:13:34 +0200 Subject: [PATCH 146/265] use this method for all not_finished orders ... --- src/Core/Webhook/Handler/WebhookHandlerBase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/Webhook/Handler/WebhookHandlerBase.php b/src/Core/Webhook/Handler/WebhookHandlerBase.php index 5de1d2e5..50f1341f 100644 --- a/src/Core/Webhook/Handler/WebhookHandlerBase.php +++ b/src/Core/Webhook/Handler/WebhookHandlerBase.php @@ -74,7 +74,6 @@ public function handle(Event $event): void } //Webhook is used to trigger unfinished order cleanup at the end of each webhook handle. - //TODO: check if webhook handler really is the place place for this $this->cleanUpNotFinishedOrders(); } From b3df9a010850ca9b834f0beaa296482735684c21 Mon Sep 17 00:00:00 2001 From: Danny Date: Mon, 10 Jun 2024 13:52:44 +0200 Subject: [PATCH 147/265] PSPAYPAL-783: added selectionList to request and parameter to "addToBasket" --- src/Controller/ProxyController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index c82d8bfc..d12edcc7 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -395,7 +395,6 @@ protected function addToBasket($qty = 1): void $basket->calculateBasket(false); } } - public function setPayPalPaymentMethod($defaultPayPalPaymentId = PayPalDefinitions::EXPRESS_PAYPAL_PAYMENT_ID): void { $session = Registry::getSession(); From 2b4706e2effc6c6f0da50ea1af887528a8a69344 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 13 Jun 2024 16:52:19 +0200 Subject: [PATCH 148/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f811d038..87c56726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007656](https://bugs.oxid-esales.com/view.php?id=7656): Fix incompatibility with Klarna-Module - better Vaulting-Check in PaymentController - disable Vaulting-Setting if Vaulting not possible +- [0007666](https://bugs.oxid-esales.com/view.php?id=7666): Fix: Price surcharges on the detail page for selection lists are not taken into account ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From e5c48b0ccd390c5f0ba3f7c8115e834f8f145c28 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 14 Jun 2024 07:53:25 +0200 Subject: [PATCH 149/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c56726..74420d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,6 +71,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - better Vaulting-Check in PaymentController - disable Vaulting-Setting if Vaulting not possible - [0007666](https://bugs.oxid-esales.com/view.php?id=7666): Fix: Price surcharges on the detail page for selection lists are not taken into account +- disable Vaulting-Option of Creditcard if Creditcard are not eligible ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 8ffa5cc0556758800b9be3ce0bec711f007f6a3a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 14 Jun 2024 14:04:49 +0200 Subject: [PATCH 150/265] fix possible maintenance if logoff on payment or order page --- src/Controller/OrderController.php | 63 +++++++++++++++------------- src/Controller/PaymentController.php | 58 +++++++++++++------------ 2 files changed, 64 insertions(+), 57 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 137fa6fb..a431f7fe 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -92,41 +92,44 @@ public function render() } $user = $this->getUser(); - $isVaultingPossible = false; - $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - if ($moduleSettings->getIsVaultingActive() && $user->getFieldData('oxpassword')) { - $isVaultingPossible = true; - } - $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); + if ($user) { + $isVaultingPossible = false; + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + if ($moduleSettings->getIsVaultingActive() && $user->getFieldData('oxpassword')) { + $isVaultingPossible = true; + } - $selectedVaultPaymentSourceIndex = $session->getVariable("selectedVaultPaymentSourceIndex"); + $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); - if ( - $isVaultingPossible && - !is_null($selectedVaultPaymentSourceIndex) && - $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") - ) { - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + $selectedVaultPaymentSourceIndex = $session->getVariable("selectedVaultPaymentSourceIndex"); - $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex( - $payPalCustomerId, - $selectedVaultPaymentSourceIndex - ); - //find out which payment token was selected by getting the index via request param - $paymentType = key($selectedPaymentToken["payment_source"]); - $paymentSource = $selectedPaymentToken["payment_source"][$paymentType]; - - $paymentDescription = ""; - if ($paymentType === "card") { - $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); - $paymentDescription = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; - } elseif ($paymentType === "paypal") { - $string = $lang->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); - $paymentDescription = $string . " " . $paymentSource["email_address"]; - } + if ( + $isVaultingPossible && + !is_null($selectedVaultPaymentSourceIndex) && + $payPalCustomerId = $user->getFieldData("oscpaypalcustomerid") + ) { + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - $this->addTplParam("vaultedPaymentDescription", $paymentDescription); + $selectedPaymentToken = $vaultingService->getVaultPaymentTokenByIndex( + $payPalCustomerId, + $selectedVaultPaymentSourceIndex + ); + //find out which payment token was selected by getting the index via request param + $paymentType = key($selectedPaymentToken["payment_source"]); + $paymentSource = $selectedPaymentToken["payment_source"][$paymentType]; + + $paymentDescription = ""; + if ($paymentType === "card") { + $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); + $paymentDescription = $paymentSource["brand"] . " " . $string . $paymentSource["last_digits"]; + } elseif ($paymentType === "paypal") { + $string = $lang->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); + $paymentDescription = $string . " " . $paymentSource["email_address"]; + } + + $this->addTplParam("vaultedPaymentDescription", $paymentDescription); + } } return parent::render(); diff --git a/src/Controller/PaymentController.php b/src/Controller/PaymentController.php index 72590131..2235660b 100644 --- a/src/Controller/PaymentController.php +++ b/src/Controller/PaymentController.php @@ -42,38 +42,42 @@ public function render() $user = $this->getUser(); - $isVaultingPossible = false; - $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - if ($moduleSettings->getIsVaultingActive() && $user->getFieldData('oxpassword')) { - $isVaultingPossible = true; - } + if ($user) { + $isVaultingPossible = false; + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + if ($moduleSettings->getIsVaultingActive() && $user->getFieldData('oxpassword')) { + $isVaultingPossible = true; + } - $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); + $this->addTplParam('oscpaypal_isVaultingPossible', $isVaultingPossible); - if ( - $isVaultingPossible && - ($paypalCustomerId = $user->getFieldData("oscpaypalcustomerid")) - ) { - $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); - if ($vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]) { - $vaultedPaymentSources = []; - foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { - foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { - if (!$this->paymentTypeExists($paymentType)) { - continue; - } - if ($paymentType === "card") { - $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); - $vaultedPaymentSources[$paymentType][] = $paymentSource["brand"] . " " . - $string . $paymentSource["last_digits"]; - } elseif ($paymentType === "paypal") { - $string = $lang->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); - $vaultedPaymentSources[$paymentType][] = $string . " " . $paymentSource["email_address"]; + if ( + $isVaultingPossible && + ($paypalCustomerId = $user->getFieldData("oscpaypalcustomerid")) + ) { + $vaultingService = Registry::get(ServiceFactory::class)->getVaultingService(); + $vaultedPaymentTokens = $vaultingService->getVaultPaymentTokens($paypalCustomerId)["payment_tokens"]; + if ($vaultedPaymentTokens) { + $vaultedPaymentSources = []; + foreach ($vaultedPaymentTokens as $vaultedPaymentToken) { + foreach ($vaultedPaymentToken["payment_source"] as $paymentType => $paymentSource) { + if (!$this->paymentTypeExists($paymentType)) { + continue; + } + if ($paymentType === "card") { + $string = $lang->translateString("OSC_PAYPAL_CARD_ENDING_IN"); + $vaultedPaymentSources[$paymentType][] = $paymentSource["brand"] . " " . + $string . $paymentSource["last_digits"]; + } elseif ($paymentType === "paypal") { + $string = $lang->translateString("OSC_PAYPAL_CARD_PAYPAL_PAYMENT"); + $vaultedPaymentSources[$paymentType][] = + $string . " " . $paymentSource["email_address"]; + } } } - } - $this->addTplParam("vaultedPaymentSources", $vaultedPaymentSources); + $this->addTplParam("vaultedPaymentSources", $vaultedPaymentSources); + } } } From 73d2ab51bff0720a3879e18f00ea9fffafd2bcf8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 09:03:27 +0000 Subject: [PATCH 151/265] Bump docker/build-push-action from 5 to 6 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 9a44db3d..b600380f 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -74,7 +74,7 @@ jobs: # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action - name: Build and push Docker image - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . platforms: linux/amd64,linux/arm64 From 2621ff2da45bd4fb5e4035779f7b7a7feb8afe75 Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 2 Jul 2024 13:55:06 +0200 Subject: [PATCH 152/265] PSPAYPAL-788: changed logger handling --- src/Core/Events/Events.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index 1692e74f..e7f649ca 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -23,6 +23,7 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; +use Psr\Log\LoggerInterface; use Symfony\Component\Console\Output\BufferedOutput; class Events From 7b33d7aca9e699bc775aacf5ca9f2b17138bf944 Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 2 Jul 2024 12:06:51 +0200 Subject: [PATCH 153/265] PSPAYPAL-787: disabled button on submit --- .../checkout/checkout_order_btn_submit_bottom.tpl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl index 793ecd7c..117b2d9f 100644 --- a/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl +++ b/views/blocks/page/checkout/checkout_order_btn_submit_bottom.tpl @@ -1,6 +1,17 @@ [{assign var="payment" value=$oView->getPayment()}] [{if "oscpaypal" == $payment->getId()}] + [{capture name="oscpaypal_madClickPrevention"}] + const submitButton = document.querySelector('#orderConfirmAgbBottom .submitButton'); + const orderConfirmAgbBottom = document.getElementById('orderConfirmAgbBottom'); + + submitButton.addEventListener('click', function() { + event.preventDefault(); + this.disabled = true; + orderConfirmAgbBottom.submit(); + }); + [{/capture}] + [{oxscript add=$smarty.capture.oscpaypal_madClickPrevention}] [{/if}] [{if "oscpaypal_pui" == $payment->getId()}] [{if $oViewConf->isFlowCompatibleTheme()}] From dda6fc24d27deee9dce42c2d28575866632d86d0 Mon Sep 17 00:00:00 2001 From: Danny Date: Mon, 1 Jul 2024 14:55:36 +0200 Subject: [PATCH 154/265] PSPAYPAL-792: added new methods in onboarding, urls to definitions --- src/Core/Onboarding/Onboarding.php | 74 +++++++++++++++++++++++++++++- src/Core/PayPalDefinitions.php | 8 +++- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index 7e382aa7..dfd71cea 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -8,7 +8,9 @@ namespace OxidSolutionCatalysts\PayPal\Core\Onboarding; use JsonException; +use OxidEsales\Eshop\Core\Exception\FileException; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; use OxidSolutionCatalysts\PayPal\Core\PartnerConfig; @@ -19,6 +21,8 @@ use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Onboarding as ApiOnboardingClient; use Psr\Log\LoggerInterface; +use Symfony\Component\Filesystem\Exception\IOException; +use Symfony\Component\Filesystem\Filesystem; class Onboarding { @@ -118,6 +122,72 @@ public function saveCredentials(array $credentials): array ]; } + /** + * @return void + */ + private function downloadAndSaveApplePayCertificate() + { + $isSandboxParameter = Registry::getRequest()->getRequestParameter('isSandbox'); + $conf = Registry::getRequest()->getRequestParameter('conf'); + $confParameter = $conf['oscPayPalSandboxMode']; + $environment = 'sandbox'; // Default to SANDBOX + if ($isSandboxParameter === "1" || ($confParameter && $confParameter === 'sandbox')) { + $environment = 'sandbox'; + } elseif ($isSandboxParameter === "0" || ($confParameter && $confParameter === 'live')) { + $environment = 'live'; + } + + $config = PayPalDefinitions::getPayPalDefinitions()[PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID]; + if (!isset($config[$environment])) { + return; + } + $filesystem = oxNew(Filesystem::class); + $this->ensureDirectoryExists($filesystem); + $this->updateCertificateIfChanged($filesystem, $environment, $config); + } + + /** + * @param Filesystem $filesystem + * @return void + */ + private function ensureDirectoryExists(Filesystem $filesystem): void + { + $directory = getShopBasePath().'.well-known/'; + try { + $filesystem->mkdir($directory); + } catch (IOException $e) { + Throw new IOException($e->getMessage()); + } + } + + /** + * @param Filesystem $filesystem + * @param string $environment + * @param array $config + * @return void + */ + private function updateCertificateIfChanged(Filesystem $filesystem, string $environment, array $config): void + { + $filename = basename(parse_url($config[$environment]['url'], PHP_URL_PATH)); + $certificateUrl = $config[$environment]['url']; + $savePath = getShopBasePath().'.well-known/' . $filename; + + $currentContent = $filesystem->exists($savePath) ? file_get_contents($savePath) : null; + + try { + $newContent = file_get_contents($certificateUrl); + } catch (FileException $e) { + return; + } + + if ($newContent !== false && $newContent !== $currentContent) { + try { + $filesystem->dumpFile($savePath, $newContent); + } catch (IOException $e) { + Throw new IOException($e->getMessage()); + } + } + } public function getOnboardingClient(bool $isSandbox, bool $withCredentials = false): ApiOnboardingClient { $paypalConfig = oxNew(PayPalConfig::class); @@ -216,7 +286,9 @@ public function saveEligibility(array $merchantInformations): array $isVaultingEligibility = true; } } - + if ($isApplePayEligibility) { + $this->downloadAndSaveApplePayCertificate(); + } $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $moduleSettings->savePuiEligibility($isPuiEligibility); $moduleSettings->saveAcdcEligibility($isAcdcEligibility); diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index c1e2490e..cc1530ab 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -92,7 +92,13 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, - 'defaulton' => true + 'defaulton' => true, + 'sandbox' => [ + 'url' => 'https://paypalobjects.com/devdoc/apple-pay/sandbox/apple-developer-merchantid-domain-association', + ], + 'live' => [ + 'url' => 'https://paypalobjects.com/devdoc/apple-pay/well-known/apple-developer-merchantid-domain-association', + ], ], //GooglePay self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ From ef28ed411248763ed518b43b9d1cc65c2211d34a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 2 Jul 2024 14:12:37 +0200 Subject: [PATCH 155/265] move cert-URLs to Constants --- src/Core/Constants.php | 6 ++++++ src/Core/PayPalDefinitions.php | 8 +------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Core/Constants.php b/src/Core/Constants.php index b630d46d..59c15142 100644 --- a/src/Core/Constants.php +++ b/src/Core/Constants.php @@ -27,6 +27,12 @@ class Constants public const PAYPAL_ONBOARDING_SANDBOX_URL = 'https://www.sandbox.paypal.com/bizsignup/partner/entry'; public const PAYPAL_ONBOARDING_LIVE_URL = 'https://www.paypal.com/bizsignup/partner/entry'; + public const PAYPAL_APPLEPAYCERT_SANDBOX_URL = + 'https://paypalobjects.com/devdoc/apple-pay/sandbox/apple-developer-merchantid-domain-association'; + + public const PAYPAL_APPLEPAYCERT_LIVE_URL = + 'https://paypalobjects.com/devdoc/apple-pay/well-known/apple-developer-merchantid-domain-association'; + public const PAYPAL_PUI_PROCESSING_INSTRUCTIONS = 'ORDER_COMPLETE_ON_PAYMENT_APPROVAL'; public const PAYPAL_PUI_FNPARAMS = 'fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99'; public const PAYPAL_PUI_FLOWID = 'Oxid_PayPal_PUI_Checkout'; diff --git a/src/Core/PayPalDefinitions.php b/src/Core/PayPalDefinitions.php index cc1530ab..c1e2490e 100644 --- a/src/Core/PayPalDefinitions.php +++ b/src/Core/PayPalDefinitions.php @@ -92,13 +92,7 @@ final class PayPalDefinitions 'constraints' => self::PAYMENT_CONSTRAINTS_PAYPAL, 'onlybrutto' => false, 'buttonpayment' => false, - 'defaulton' => true, - 'sandbox' => [ - 'url' => 'https://paypalobjects.com/devdoc/apple-pay/sandbox/apple-developer-merchantid-domain-association', - ], - 'live' => [ - 'url' => 'https://paypalobjects.com/devdoc/apple-pay/well-known/apple-developer-merchantid-domain-association', - ], + 'defaulton' => true ], //GooglePay self::GOOGLEPAY_PAYPAL_PAYMENT_ID => [ From 73d7d4d0142833a3c9849baad6024af0a9087785 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 2 Jul 2024 14:13:17 +0200 Subject: [PATCH 156/265] use sandbox-mode via moduleConfig --- src/Core/Onboarding/Onboarding.php | 44 ++++++++++-------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/src/Core/Onboarding/Onboarding.php b/src/Core/Onboarding/Onboarding.php index dfd71cea..22036d26 100755 --- a/src/Core/Onboarding/Onboarding.php +++ b/src/Core/Onboarding/Onboarding.php @@ -8,10 +8,8 @@ namespace OxidSolutionCatalysts\PayPal\Core\Onboarding; use JsonException; -use OxidEsales\Eshop\Core\Exception\FileException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; -use OxidSolutionCatalysts\PayPal\Service\Logger; +use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\Config as PayPalConfig; use OxidSolutionCatalysts\PayPal\Core\PartnerConfig; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; @@ -127,23 +125,11 @@ public function saveCredentials(array $credentials): array */ private function downloadAndSaveApplePayCertificate() { - $isSandboxParameter = Registry::getRequest()->getRequestParameter('isSandbox'); - $conf = Registry::getRequest()->getRequestParameter('conf'); - $confParameter = $conf['oscPayPalSandboxMode']; - $environment = 'sandbox'; // Default to SANDBOX - if ($isSandboxParameter === "1" || ($confParameter && $confParameter === 'sandbox')) { - $environment = 'sandbox'; - } elseif ($isSandboxParameter === "0" || ($confParameter && $confParameter === 'live')) { - $environment = 'live'; - } - - $config = PayPalDefinitions::getPayPalDefinitions()[PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID]; - if (!isset($config[$environment])) { - return; - } + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); + $isSandbox = $moduleSettings->isSandbox(); $filesystem = oxNew(Filesystem::class); $this->ensureDirectoryExists($filesystem); - $this->updateCertificateIfChanged($filesystem, $environment, $config); + $this->updateCertificateIfChanged($filesystem, $isSandbox); } /** @@ -152,11 +138,11 @@ private function downloadAndSaveApplePayCertificate() */ private function ensureDirectoryExists(Filesystem $filesystem): void { - $directory = getShopBasePath().'.well-known/'; + $directory = getShopBasePath() . '.well-known/'; try { $filesystem->mkdir($directory); } catch (IOException $e) { - Throw new IOException($e->getMessage()); + throw new IOException($e->getMessage()); } } @@ -166,25 +152,23 @@ private function ensureDirectoryExists(Filesystem $filesystem): void * @param array $config * @return void */ - private function updateCertificateIfChanged(Filesystem $filesystem, string $environment, array $config): void + private function updateCertificateIfChanged(Filesystem $filesystem, bool $isSandbox): void { - $filename = basename(parse_url($config[$environment]['url'], PHP_URL_PATH)); - $certificateUrl = $config[$environment]['url']; - $savePath = getShopBasePath().'.well-known/' . $filename; + $certificateUrl = $isSandbox ? + Constants::PAYPAL_APPLEPAYCERT_SANDBOX_URL : + Constants::PAYPAL_APPLEPAYCERT_LIVE_URL; + $filename = basename(parse_url($certificateUrl, PHP_URL_PATH)); + $savePath = getShopBasePath() . '.well-known/' . $filename; $currentContent = $filesystem->exists($savePath) ? file_get_contents($savePath) : null; - try { - $newContent = file_get_contents($certificateUrl); - } catch (FileException $e) { - return; - } + $newContent = file_get_contents($certificateUrl); if ($newContent !== false && $newContent !== $currentContent) { try { $filesystem->dumpFile($savePath, $newContent); } catch (IOException $e) { - Throw new IOException($e->getMessage()); + throw new IOException($e->getMessage()); } } } From 01096904bd2610449a37a2c975a08fd919082acc Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 2 Jul 2024 14:17:06 +0200 Subject: [PATCH 157/265] ChangeLog & new RC --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74420d9d..93822dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - disable Vaulting-Setting if Vaulting not possible - [0007666](https://bugs.oxid-esales.com/view.php?id=7666): Fix: Price surcharges on the detail page for selection lists are not taken into account - disable Vaulting-Option of Creditcard if Creditcard are not eligible +- Automatically save Apple Pay certificates during the Apple Pay eligibility check ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 2eaad5ba840be52e326e76e9661064cfbae03ec0 Mon Sep 17 00:00:00 2001 From: Danny Date: Tue, 2 Jul 2024 15:14:08 +0200 Subject: [PATCH 158/265] PSPAYPAL-793: added redirect-param for express --- src/Controller/ProxyController.php | 6 +++++- src/Core/ViewConfig.php | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index d12edcc7..fe263984 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -372,7 +372,11 @@ public function cancelPayPalPayment() { PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); - Registry::getUtils()->redirect(Registry::getConfig()->getShopSecureHomeURL() . 'cl=payment', false, 301); + $redirect = Registry::getRequest()->getRequestParameter('redirect'); + if ($redirect === "1" ) { + Registry::getUtils()->redirect(Registry::getConfig()->getShopSecureHomeURL() . 'cl=payment', false, 301); + } + exit; } protected function addToBasket($qty = 1): void diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index c77b2637..3820c1ef 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -146,7 +146,7 @@ public function getPayPalPuiFlowId(): string */ public function getCancelPayPalPaymentUrl(): string { - return $this->getSslSelfLink() . 'cl=oscpaypalproxy&fnc=cancelPayPalPayment'; + return $this->getSslSelfLink() . 'cl=oscpaypalproxy&fnc=cancelPayPalPayment&redirect=1'; } /** From 8572ac323c518c4386daf30ad500c8f47dfab0a7 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 4 Jul 2024 11:31:22 +0200 Subject: [PATCH 159/265] CHANGELOG & Version & CodeStyle --- CHANGELOG.md | 1 + src/Controller/ProxyController.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93822dd2..534e061d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007666](https://bugs.oxid-esales.com/view.php?id=7666): Fix: Price surcharges on the detail page for selection lists are not taken into account - disable Vaulting-Option of Creditcard if Creditcard are not eligible - Automatically save Apple Pay certificates during the Apple Pay eligibility check +- [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index fe263984..7b7e5e9f 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -373,7 +373,7 @@ public function cancelPayPalPayment() PayPalSession::unsetPayPalOrderId(); Registry::getSession()->getBasket()->setPayment(null); $redirect = Registry::getRequest()->getRequestParameter('redirect'); - if ($redirect === "1" ) { + if ($redirect === "1") { Registry::getUtils()->redirect(Registry::getConfig()->getShopSecureHomeURL() . 'cl=payment', false, 301); } exit; From 48a36c95372881cdc53265ae5c460d0f3f141162 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 4 Jul 2024 11:41:53 +0200 Subject: [PATCH 160/265] CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 534e061d..9443a7c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - disable Vaulting-Option of Creditcard if Creditcard are not eligible - Automatically save Apple Pay certificates during the Apple Pay eligibility check - [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool +- [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool +- [0007675](https://bugs.oxid-esales.com/view.php?id=7675): fix the possibility to finish order without redirect and login to Paypal ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From c87157d4129f6e7543a0aa580def95835a8d7719 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 4 Jul 2024 13:37:17 +0200 Subject: [PATCH 161/265] Change behavoir to show a better understandable error message about what happened. --- CHANGELOG.md | 2 +- src/Core/Events/Events.php | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9443a7c6..cd9bb573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,8 +74,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - disable Vaulting-Option of Creditcard if Creditcard are not eligible - Automatically save Apple Pay certificates during the Apple Pay eligibility check - [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool -- [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool - [0007675](https://bugs.oxid-esales.com/view.php?id=7675): fix the possibility to finish order without redirect and login to Paypal +- [0007676](https://bugs.oxid-esales.com/view.php?id=7676): If we have a corrupted generated_services.yaml and try to deactivate the module via the admin, we will display a more understandable error message about what happened. ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index e7f649ca..5ca025cb 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -10,6 +10,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Events; use OxidEsales\DoctrineMigrationWrapper\MigrationsBuilder; +use OxidEsales\Eshop\Application\Model\Payment as EshopModelPayment; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface; @@ -23,7 +24,6 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Container\NotFoundExceptionInterface; -use Psr\Log\LoggerInterface; use Symfony\Component\Console\Output\BufferedOutput; class Events @@ -52,6 +52,24 @@ public static function onActivate(): void */ public static function onDeactivate(): void { + $activePayments = []; + foreach (PayPalDefinitions::getPayPalDefinitions() as $paymentId => $paymentDefinitions) { + $paymentMethod = oxNew(EshopModelPayment::class); + if ( + $paymentMethod->load($paymentId) && + $paymentMethod->getFieldData('oxactive') + ) { + $activePayments[] = $paymentId; + $paymentMethod->assign([ + 'oxactive' => false + ]); + $paymentMethod->save(); + } + } + $service = self::getModuleSettingsService(); + if ($service) { + $service->saveActivePayments($activePayments); + } } /** From 1db03eeed278e2a386133d3bde4f6afdb1b7dcd1 Mon Sep 17 00:00:00 2001 From: MarkusMichalski Date: Wed, 17 Jul 2024 11:30:25 +0200 Subject: [PATCH 162/265] PSPAYPAL-801 deactivated Giropay, added hint message, disabled activation box --- metadata.php | 23 ++++++++++++++++++++++- src/Core/Events/Events.php | 6 +++++- src/Service/StaticContent.php | 15 +++++++++++++++ views/de/admin_translations.php | 3 +++ views/en/admin_translations.php | 3 +++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/metadata.php b/metadata.php index 7c9424fc..b84bfb9b 100755 --- a/metadata.php +++ b/metadata.php @@ -199,7 +199,28 @@ [ 'template' => 'page/checkout/basket.tpl', 'block' => 'basket_btn_next_bottom', - 'file' => 'views/smarty/frontend/blocks/page/checkout/inc/basket__basket_btn_next_bottom.tpl', + 'file' => '/views/blocks/page/checkout/basket_btn_next_bottom.tpl', + ], + [ + 'template' => 'widget/minibasket/minibasket.tpl', + 'block' => 'dd_layout_page_header_icon_menu_minibasket_functions', + 'file' => '/views/blocks/widget/minibasket/dd_layout_page_header_icon_menu_minibasket_functions.tpl', + ], + [ + 'template' => 'payment_main.tpl', + 'block' => 'admin_payment_main_form', + 'file' => '/views/blocks/admin/admin_payment_main_form.tpl', + ], + // @Todo PAYPAL-486: Using the same file, with 2 themes. Should be more generic, if possible. + [ + 'template' => 'page/checkout/payment.tpl', + 'block' => 'select_payment', + 'file' => '/views/blocks/page/checkout/select_payment.tpl', + ], + [ + 'template' => 'page/checkout/payment.tpl', + 'block' => 'change_payment', + 'file' => '/views/blocks/page/checkout/change_payment.tpl', ], [ 'template' => 'page/checkout/basket.tpl', diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index 5ca025cb..e39c97d0 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -59,7 +59,11 @@ public static function onDeactivate(): void $paymentMethod->load($paymentId) && $paymentMethod->getFieldData('oxactive') ) { - $activePayments[] = $paymentId; + if (PayPalDefinitions::isDeprecatedPayment($paymentId)) { + //dont set deprecated payments to active payment list + } else { + $activePayments[] = $paymentId; + } $paymentMethod->assign([ 'oxactive' => false ]); diff --git a/src/Service/StaticContent.php b/src/Service/StaticContent.php index 16d59a18..8696f27c 100644 --- a/src/Service/StaticContent.php +++ b/src/Service/StaticContent.php @@ -118,6 +118,21 @@ protected function deactivatePaymentMethod(string $paymentId) : void { } } + /** + * Try to load payment model based on given id an set payment inactive + * + * @param string $paymentId + * @return void + * @throws \Exception + */ + protected function deactivatePaymentMethod(string $paymentId) : void { + $paymentModel = oxNew(EshopModelPayment::class); + if ($paymentModel->load($paymentId)) { + $paymentModel->oxpayments__oxactive = new Field(false); + $paymentModel->save(); + } + } + public function ensureStaticContents(): void { foreach (PayPalDefinitions::getPayPalStaticContents() as $content) { diff --git a/views/de/admin_translations.php b/views/de/admin_translations.php index fa9016da..cc46fec1 100755 --- a/views/de/admin_translations.php +++ b/views/de/admin_translations.php @@ -284,4 +284,7 @@ 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Übernahme der Lieferadresse von GooglePay', 'OSC_PAYPAL_INSTALLPROCESS_FAILED' => 'Da das Modul nicht korrekt per Composer installiert ist, sind Fehler bei der (De-)Aktivierung des Moduls aufgetreten. Bitte installieren Sie das Modul via Composer frisch und wiederholen den Vorgang.', + + // PayPal Payment + 'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'Diese PayPal Zahlungsart kann nicht mehr aktiviert werden, da diese demnächst entfernt wird!', ]; diff --git a/views/en/admin_translations.php b/views/en/admin_translations.php index 3b9faa05..35b66605 100755 --- a/views/en/admin_translations.php +++ b/views/en/admin_translations.php @@ -285,4 +285,7 @@ 'HELP_OSC_OSC_PAYPAL_GOOGLEPAY_ADRESS_ACTIVATE' => 'Takeover delivery address from googlepay', 'OSC_PAYPAL_INSTALLPROCESS_FAILED' => 'Because the module was not installed correctly via Composer, errors occurred during the (de)activation of the module. Please reinstall the module via composer and repeat the process.', + + // PayPal Payment + 'OSC_PAYPAL_PAYMENT_DEPRECATED' => 'This PayPal payment method can no longer be activated as it will be removed soon!', ]; From 280a2cd5136639361ba07eb3d3b333885358c3ea Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 19 Jul 2024 14:46:55 +0200 Subject: [PATCH 163/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd9bb573..d46e2714 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Introduce ApplePay-Payment - use PayPal-Client v2.0.14 - add Default-Shippingcosts for PP-Express to prevent overcharge. +- mark GiroPay as deprecated ## [2.4.0] - 2024-04-04 From cc418004240c9e471ac0ba17741f47a164418a23 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 19 Jul 2024 15:32:03 +0200 Subject: [PATCH 164/265] fix: AmountPatch only if Amount != 0,0 (cherry picked from commit 4682c868cd4c79ab7adf9731f8c60896d4ac3db0) --- src/Core/PatchRequestFactory.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Core/PatchRequestFactory.php b/src/Core/PatchRequestFactory.php index b72d0cae..94ed8d10 100644 --- a/src/Core/PatchRequestFactory.php +++ b/src/Core/PatchRequestFactory.php @@ -15,7 +15,6 @@ use OxidEsales\Eshop\Application\Model\Country; use OxidEsales\Eshop\Application\Model\State; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\PayPalRequestAmountFactory; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Item; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Patch; From 443ee56efe254efd09a2a53ab6ab52ebe2a284fa Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 10:54:55 +0000 Subject: [PATCH 165/265] Update tag to v2.0.15 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index 5b0c9c43..a0252245 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v1.0.10 \ No newline at end of file +v2.0.15 \ No newline at end of file From b6ad5ec5f891789a9125168e2bcc5829051dece9 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 16 Jul 2024 16:19:55 +0200 Subject: [PATCH 166/265] add actionHash to make Request Unique --- src/Core/ServiceFactory.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/ServiceFactory.php b/src/Core/ServiceFactory.php index 036c15d5..36886880 100644 --- a/src/Core/ServiceFactory.php +++ b/src/Core/ServiceFactory.php @@ -10,6 +10,7 @@ namespace OxidSolutionCatalysts\PayPal\Core; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Api\VaultingService; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Client; use OxidSolutionCatalysts\PayPalApi\Service\Partner; From 1c35d66526510e24e1443efe4297a9fd9ee6fe6c Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 16 Jul 2024 16:32:08 +0200 Subject: [PATCH 167/265] Fetch more Informations for Order. If Order is completed no capture are necessary. In this case return the fetched Order. --- src/Service/Payment.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Service/Payment.php b/src/Service/Payment.php index c0e589dd..ed49c8c6 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -331,6 +331,7 @@ public function doCapturePayPalOrder( $checkoutOrderId, $shopOrderId ); + /** @var $result ApiOrderModel */ $result = $orderService->capturePaymentForOrder( '', From 137dee6cce9a5c4575f3c59d6b3940c4d0a003b2 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 16 Jul 2024 16:44:08 +0200 Subject: [PATCH 168/265] CHANGELOG --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d46e2714..04ce0e7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007681](https://bugs.oxid-esales.com/view.php?id=7681): fix OXID Logger.ERROR: Call to a member function getFieldData() on bool - [0007675](https://bugs.oxid-esales.com/view.php?id=7675): fix the possibility to finish order without redirect and login to Paypal - [0007676](https://bugs.oxid-esales.com/view.php?id=7676): If we have a corrupted generated_services.yaml and try to deactivate the module via the admin, we will display a more understandable error message about what happened. +- introduce ActionHash to make the PayPal-Request-ID more unique +- use PayPal-Client v2.0.15 ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 2f14683dbe038c6a84a81a40ac783bf06dddc5bc Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 19 Jul 2024 11:06:05 +0200 Subject: [PATCH 169/265] Set all Request-Methods uppercase because of Method-Check-Restriction --- src/Core/Api/VaultingService.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index cb94274b..dc20d0f5 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -32,7 +32,6 @@ public function generateUserIdToken($payPalCustomerId = false): array } $path = '/v1/oauth2/token'; - $method = 'post'; $response = $this->send('POST', $path, $params, $headers); $body = $response->getBody(); @@ -69,7 +68,6 @@ public function createVaultSetupToken(bool $card = false): array $headers = $this->getVaultingHeaders(); $path = '/v3/vault/setup-tokens'; - $method = 'post'; $response = $this->send( 'POST', @@ -177,7 +175,6 @@ public function createVaultPaymentToken($setupToken) $headers = $this->getVaultingHeaders(); $path = '/v3/vault/payment-tokens'; - $method = 'post'; $requestBody = [ "payment_source" => [ @@ -202,9 +199,8 @@ public function getVaultPaymentTokens($paypalCustomerId) } $path = '/v3/vault/payment-tokens?customer_id=' . $paypalCustomerId; - $method = 'get'; - $response = $this->send($method, $path); + $response = $this->send('GET', $path); $body = $response->getBody(); return json_decode((string)$body, true); From 55d93c52ba30d03e9969b74d76cdea3e9a136f77 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Wed, 7 Aug 2024 14:16:15 +0200 Subject: [PATCH 170/265] fix createGooglePayOrder during onApprove --- src/Model/Order.php | 2 +- src/Model/PaymentGateway.php | 13 +++--- views/smarty/frontend/blocks/googlepay.tpl | 49 ++++++++++------------ 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/Model/Order.php b/src/Model/Order.php index f513c5dd..f5b53d08 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -156,7 +156,7 @@ public function finalizeOrderAfterExternalPayment(string $payPalOrderId, bool $f $transactionId = null; $payPalPaymentSuccess = true; - if ($isPayPalACDC && $forceFetchDetails || $isPaypalApplePay|| $isPaypalGooglePay) { + if (($isPayPalACDC && $forceFetchDetails) || $isPaypalGooglePay || $isPaypalApplePay) { $payPalApiOrder = $paymentService->fetchOrderFields($payPalOrderId); if ($this->isPayPalOrderCompleted($payPalApiOrder)) { $this->markOrderPaid(); diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index fb2636f5..80995ef0 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -46,17 +46,18 @@ public function executePayment($amount, &$order) $success = parent::executePayment($amount, $order); } $paypalOrderId = ''; - if ($sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID) { + if ($sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID || $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { $paypalOrderId = Registry::getRequest()->getRequestParameter('orderID'); } if ( $success && - $paymentService->isPayPalPayment() && - ($capture = $order->getOrderPaymentCapture($paypalOrderId)) && - (string) $capture->status === 'COMPLETED' + $paymentService->isPayPalPayment() ) { - $order->setTransId($capture->id); - $order->markOrderPaid(); + $capture = $order->getOrderPaymentCapture($paypalOrderId); + if ($capture && (string) $capture->status === 'COMPLETED') { + $order->setTransId($capture->id); + $order->markOrderPaid(); + } } return $success; diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index f8ab1552..6d5befde 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -224,9 +224,9 @@ return res.json(); }).then(function (data) { [{if $oPPconfig->isSandbox()}] - console.log('onCreated captureData debug'); + console.log('onCreated data debug'); console.log(data); - console.log('onCreated captureData debugend'); + console.log('onCreated data debugend'); [{/if}] var goNext = Array.isArray(data.location) && data.location[0]; @@ -239,34 +239,27 @@ } }); } + function onApprove(confirmOrderResponse, actions) { - var form = document.createElement("form"); - form.setAttribute("method", "post"); - form.setAttribute("action", `[{$sSelfLink|cat:"cl=order&fnc=createGooglePayOrder&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken|cat:"&sDeliveryAddressMD5="|cat:$oView->getDeliveryAddressMD5()}]`); - var orderIDField = document.createElement("input"); - orderIDField.setAttribute("type", "hidden"); - orderIDField.setAttribute("name", "orderID"); - orderIDField.setAttribute("value", confirmOrderResponse.id); - form.appendChild(orderIDField); - document.body.appendChild(form); - form.submit(); - form.onsubmit = function (event) { - event.preventDefault(); // Prevent the form from submitting normally - fetch(form.action, { - method: 'post', - body: new FormData(form) - }).then(function (res) { - return res.json(); - }).then(function (data) { - [{if $oPPconfig->isSandbox()}] - console.log(data); - [{/if}] - if (data.status === "ERROR") { - location.reload(); - } - }); - }; + const url = '[{$sSelfLink|cat:"cl=order&fnc=createGooglePayOrder&context=continue&aid="|cat:$aid|cat:"&stoken="|cat:$sToken|cat:"&sDeliveryAddressMD5="|cat:$oView->getDeliveryAddressMD5()}]'; + createData = new FormData(); + createData.append('orderID', confirmOrderResponse.id); + fetch(url, { + method: 'POST', + body: createData + }).then(function (res) { + return res.json(); + }).then(function (data) { + [{if $oPPconfig->isSandbox()}] + console.log('onApprove data debug'); + console.log(data); + console.log('onApprove data debugend'); + [{/if}] + if (data.status === "ERROR") { + location.reload(); + } + }); } }); } From 1ef48d2e1cbdb68fd4f974bc130efb27070b43b0 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 8 Aug 2024 12:52:34 +0200 Subject: [PATCH 171/265] fix CodeStyle --- src/Controller/Admin/PayPalConfigController.php | 2 +- src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php | 8 ++++++-- src/Model/PaymentGateway.php | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Controller/Admin/PayPalConfigController.php b/src/Controller/Admin/PayPalConfigController.php index ae0f5a37..f4a6abef 100644 --- a/src/Controller/Admin/PayPalConfigController.php +++ b/src/Controller/Admin/PayPalConfigController.php @@ -221,7 +221,7 @@ protected function checkEligibility(array $confArr): void $moduleSettings->save('oscPayPalSetVaulting', false); } } - } catch (ClientException|ApiException $exception) { + } catch (ClientException | ApiException $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); diff --git a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php index a8d3d0db..2b30008d 100644 --- a/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php +++ b/src/Core/Webhook/Handler/CheckoutOrderApprovedHandler.php @@ -104,9 +104,13 @@ private function needsCapture(array $eventPayload): bool private function isCompleted(array $eventPayload): bool { - $condition1 = isset($eventPayload['status'], $eventPayload['purchase_units'][0]['payments']['captures'][0]['status']); + $condition1 = isset( + $eventPayload['status'], + $eventPayload['purchase_units'][0]['payments']['captures'][0]['status'] + ); $condition2 = $this->getStatusFromResource($eventPayload) === OrderResponse::STATUS_COMPLETED; - $condition3 = $eventPayload['purchase_units'][0]['payments']['captures'][0]['status'] === Capture::STATUS_COMPLETED; + $condition3 = $eventPayload['purchase_units'][0]['payments']['captures'][0]['status'] === + Capture::STATUS_COMPLETED; return ($condition1 && $condition2 && $condition3); } } diff --git a/src/Model/PaymentGateway.php b/src/Model/PaymentGateway.php index 80995ef0..d71970ae 100644 --- a/src/Model/PaymentGateway.php +++ b/src/Model/PaymentGateway.php @@ -46,7 +46,10 @@ public function executePayment($amount, &$order) $success = parent::executePayment($amount, $order); } $paypalOrderId = ''; - if ($sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID || $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID) { + if ( + $sessionPaymentId === PayPalDefinitions::APPLEPAY_PAYPAL_PAYMENT_ID || + $sessionPaymentId === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID + ) { $paypalOrderId = Registry::getRequest()->getRequestParameter('orderID'); } if ( From b6b44f65964cdbdd2dfdd5439ce72908d202c781 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 8 Aug 2024 13:04:40 +0200 Subject: [PATCH 172/265] CHANGELOG --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04ce0e7a..8d041b94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,13 +77,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007675](https://bugs.oxid-esales.com/view.php?id=7675): fix the possibility to finish order without redirect and login to Paypal - [0007676](https://bugs.oxid-esales.com/view.php?id=7676): If we have a corrupted generated_services.yaml and try to deactivate the module via the admin, we will display a more understandable error message about what happened. - introduce ActionHash to make the PayPal-Request-ID more unique -- use PayPal-Client v2.0.15 ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore - Introduce GooglePay-Payment - Introduce ApplePay-Payment -- use PayPal-Client v2.0.14 +- use PayPal-Client v2.0.15 - add Default-Shippingcosts for PP-Express to prevent overcharge. - mark GiroPay as deprecated From ba627e58efecffcaac9d10f26cc7f69ceb9a5eda Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 13 Aug 2024 17:03:57 +0200 Subject: [PATCH 173/265] delete the Basket if PP-Overlay is closed --- src/Controller/ProxyController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 7b7e5e9f..411ff0b1 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -370,8 +370,8 @@ public function approveOrder() public function cancelPayPalPayment() { - PayPalSession::unsetPayPalOrderId(); - Registry::getSession()->getBasket()->setPayment(null); + PayPalSession::unsetPayPalSession(); + Registry::getSession()->getBasket()->deleteBasket(); $redirect = Registry::getRequest()->getRequestParameter('redirect'); if ($redirect === "1") { Registry::getUtils()->redirect(Registry::getConfig()->getShopSecureHomeURL() . 'cl=payment', false, 301); From 4b82d558b86a2a834ee59418e69a1f67b3002fb5 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 16 Aug 2024 09:36:50 +0200 Subject: [PATCH 174/265] automatic cancel orders instead of delete --- src/Service/OrderRepository.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Service/OrderRepository.php b/src/Service/OrderRepository.php index 0b036f88..e7cef073 100644 --- a/src/Service/OrderRepository.php +++ b/src/Service/OrderRepository.php @@ -171,8 +171,6 @@ public function cleanUpNotFinishedOrders(): void if ($order->load($id)) { // storno $order->cancelOrder(); - // delete - $order->delete(); } } } From e3b81934d8fb5ecc32e0dc2e03c53812480e4000 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 16 Aug 2024 13:41:43 +0200 Subject: [PATCH 175/265] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2609a855..4320f099 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,10 @@ PayPal checkout integration for OXID eShop 6.1 and above. ## Documentation * Official [German PayPal Checkout for OXID 6.1 to 6.2 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/de/1.2/) -* Official [German PayPal Checkout for OXID 6.3 to 6.5 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/de/2.4/) +* Official [German PayPal Checkout for OXID 6.3 to 6.5 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/de/2.5/) * Official [German PayPal Checkout for OXID from 7.0 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/de/3.3/) * Official [English PayPal Checkout for OXID 6.1 to 6.2 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/en/1.2/) -* Official [English PayPal Checkout for OXID 6.3 to 6.5 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/en/2.4/) +* Official [English PayPal Checkout for OXID 6.3 to 6.5 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/en/2.5/) * Official [English PayPal Checkout for OXID from 7.0 documentation](https://docs.oxid-esales.com/modules/paypal-checkout/en/3.3/) @@ -71,4 +71,4 @@ Running codeception tests example with specific host/browser/testgroup: in OXID 6.3 and above: ``` SELENIUM_SERVER_HOST=seleniumchrome BROWSER_NAME=chrome vendor/bin/runtests-codeception --group=examplegroup -``` \ No newline at end of file +``` From c17ab5b38fe7cc5762c9dd49b2db0b103dc21363 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 16 Aug 2024 14:30:09 +0200 Subject: [PATCH 176/265] If Delivery is set PseudoDeliveryCosts are not necessary... --- metadata.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata.php b/metadata.php index b84bfb9b..ed5dcf00 100755 --- a/metadata.php +++ b/metadata.php @@ -450,7 +450,7 @@ [ 'name' => 'oscPayPalBannersProductDetailsPageSelector', 'type' => 'str', - 'value' => '.breadcrumb-wrapper > .container-xxl', + 'value' => '#detailsItemsPager', 'group' => null ], [ From 6235727efc251bcc3e636a485d7f1a2675d172cf Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 16 Aug 2024 14:34:42 +0200 Subject: [PATCH 177/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d041b94..7d5b819a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007675](https://bugs.oxid-esales.com/view.php?id=7675): fix the possibility to finish order without redirect and login to Paypal - [0007676](https://bugs.oxid-esales.com/view.php?id=7676): If we have a corrupted generated_services.yaml and try to deactivate the module via the admin, we will display a more understandable error message about what happened. - introduce ActionHash to make the PayPal-Request-ID more unique +- [0007695](https://bugs.oxid-esales.com/view.php?id=7695): Fix: if DeliverySet is set in Frontend, then do not add any PseudoDeliveryCosts for PPExpress ### NEW - PayPal-Request-Id based on serialized body, no extra PayPal-Request-Id necessary anymore From 5a8eee5682ddac67790f8996c74328cbe17bd3fa Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 16 Aug 2024 18:36:26 +0200 Subject: [PATCH 178/265] release v2.5.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d5b819a..a2adf711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,7 +59,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support -## [2.5.0] - 2024-??-?? +## [2.5.0] - 2024-08-16 ### FIX From 6c61a1659d61c57e3c0ad727605a1448b399a096 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 09:26:14 +0200 Subject: [PATCH 179/265] fix SQL: Date should be in the past, not in the future --- src/Service/OrderRepository.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Service/OrderRepository.php b/src/Service/OrderRepository.php index e7cef073..64e3ffef 100644 --- a/src/Service/OrderRepository.php +++ b/src/Service/OrderRepository.php @@ -142,7 +142,6 @@ public function cleanUpNotFinishedOrders(): void $sessiontime = (int)$this->config->getConfigParam('oscPayPalStartTimeCleanUpOrders'); $shopId = $this->config->getShopId(); - /** @var QueryBuilder $queryBuilder */ $queryBuilder = $this->queryBuilderFactory->create(); $parameters = [ @@ -160,11 +159,11 @@ public function cleanUpNotFinishedOrders(): void 'oxpaymenttype', $queryBuilder->expr()->literal('%' . $parameters['oxpaymenttype'] . '%') )) - ->andWhere('oxorderdate + interval :sessiontime MINUTE > now()'); + ->andWhere('oxorderdate < now() - interval :sessiontime MINUTE'); $ids = $queryBuilder->setParameters($parameters) ->execute() - ->fetchAll(PDO::FETCH_COLUMN); + ->fetchAllAssociative(); foreach ($ids as $id) { $order = oxNew(EshopModelOrder::class); From 8975bcd80a1fbb375806f476f1c12e76b75e7372 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 14:23:15 +0200 Subject: [PATCH 180/265] CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2adf711..f344f19d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - first Version for OXID7 with APEX-Theme as Twig-Frontend-Standard-Theme, without Smarty-Support +## [2.5.1] - 2024-??-?? + +### FIX + +- [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders + ## [2.5.0] - 2024-08-16 ### FIX From d440a0a74a0254dfd156e4e643b499e70ca074b7 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 14:17:14 +0200 Subject: [PATCH 181/265] provide oxrights for Buttons and additional blocks for overwriting --- views/smarty/frontend/blocks/applepay.tpl | 17 ++++++++++------- views/smarty/frontend/blocks/googlepay.tpl | 7 ++++++- views/smarty/frontend/paymentbuttons.tpl | 2 ++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/views/smarty/frontend/blocks/applepay.tpl b/views/smarty/frontend/blocks/applepay.tpl index 1891b609..10047e65 100644 --- a/views/smarty/frontend/blocks/applepay.tpl +++ b/views/smarty/frontend/blocks/applepay.tpl @@ -1,3 +1,5 @@ +[{block name="oscpaypal_applepay"}] +[{oxhasrights ident="PAYWITHAPPLEPAY"}] [{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] [{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] [{assign var="config" value=$oViewConf->getPayPalCheckoutConfig()}] @@ -11,8 +13,8 @@ float: right; } -[{if $phpstorm}][{/if}] +[{/capture}] +[{oxscript include="https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js" }] +[{oxscript add=$smarty.capture.detailsApplePayScript}] +[{/oxhasrights}] +[{/block}] diff --git a/views/smarty/frontend/blocks/googlepay.tpl b/views/smarty/frontend/blocks/googlepay.tpl index 6d5befde..d6283a60 100644 --- a/views/smarty/frontend/blocks/googlepay.tpl +++ b/views/smarty/frontend/blocks/googlepay.tpl @@ -1,3 +1,5 @@ +[{block name="oscpaypal_googlepay"}] +[{oxhasrights ident="PAYWITHGOOGLEPAY"}] [{assign var="sToken" value=$oViewConf->getSessionChallengeToken()}] [{assign var="sSelfLink" value=$oViewConf->getSslSelfLink()|replace:"&":"&"}] [{assign var="oPPconfig" value=$oViewConf->getPayPalCheckoutConfig()}] @@ -9,7 +11,7 @@ } [{capture name="detailsGooglePayScript"}] -[{if false}][{/if}] [{oxscript add=$paypal_init}] + [{/oxhasrights}] [{/block}] From 9c451313498a3b4dc464e5064f6ad040d382bed5 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 14:19:19 +0200 Subject: [PATCH 182/265] CHANGELOG --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f344f19d..524a72d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders +## [2.5.1] - 2024-??-?? + +### FIX + +- [0007584](https://bugs.oxid-esales.com/view.php?id=7584): Provide additional oxrights-elements for PayPal-Express, ApplePay and GooglePay-Buttons + ## [2.5.0] - 2024-08-16 ### FIX From 1565021cc58d3bc68e903af65a03e38b233c587c Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 14:33:59 +0200 Subject: [PATCH 183/265] Removing payment method deactivation during module deactivation. Merchants must now do this themselves --- CHANGELOG.md | 6 ------ metadata.php | 6 +++--- src/Core/Events/Events.php | 22 ---------------------- src/Service/ModuleSettings.php | 10 ++++------ src/Service/StaticContent.php | 25 +++++++++++++------------ 5 files changed, 20 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 524a72d4..f344f19d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,12 +65,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders -## [2.5.1] - 2024-??-?? - -### FIX - -- [0007584](https://bugs.oxid-esales.com/view.php?id=7584): Provide additional oxrights-elements for PayPal-Express, ApplePay and GooglePay-Buttons - ## [2.5.0] - 2024-08-16 ### FIX diff --git a/metadata.php b/metadata.php index ed5dcf00..4ed95e4b 100755 --- a/metadata.php +++ b/metadata.php @@ -570,9 +570,9 @@ 'group' => null ], [ - 'name' => 'oscPayPalSetVaulting', - 'type' => 'bool', - 'value' => true, + 'name' => 'oscPayPalActivePayments', + 'type' => 'arr', + 'value' => [], 'group' => null ], [ diff --git a/src/Core/Events/Events.php b/src/Core/Events/Events.php index e39c97d0..89e4f740 100644 --- a/src/Core/Events/Events.php +++ b/src/Core/Events/Events.php @@ -52,28 +52,6 @@ public static function onActivate(): void */ public static function onDeactivate(): void { - $activePayments = []; - foreach (PayPalDefinitions::getPayPalDefinitions() as $paymentId => $paymentDefinitions) { - $paymentMethod = oxNew(EshopModelPayment::class); - if ( - $paymentMethod->load($paymentId) && - $paymentMethod->getFieldData('oxactive') - ) { - if (PayPalDefinitions::isDeprecatedPayment($paymentId)) { - //dont set deprecated payments to active payment list - } else { - $activePayments[] = $paymentId; - } - $paymentMethod->assign([ - 'oxactive' => false - ]); - $paymentMethod->save(); - } - } - $service = self::getModuleSettingsService(); - if ($service) { - $service->saveActivePayments($activePayments); - } } /** diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index 046f6f5d..aca3cc47 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -390,9 +390,11 @@ public function isSandboxGooglePayEligibility(): bool return (bool)$this->getSettingValue('oscPayPalSandboxGooglePayEligibility'); } - public function getIsVaultingActive(): bool + public function getActivePayments(): array { - return (bool)$this->getSettingValue('oscPayPalSetVaulting'); + /** @var array|null $activePayments */ + $activePayments = $this->getSettingValue('oscPayPalActivePayments'); + return $activePayments ?: []; } /** @@ -505,10 +507,6 @@ public function saveWebhookId(string $webhookId): void } } - public function saveActivePayments(array $activePayments): void - { - $this->save('oscPayPalActivePayments', $activePayments); - } public function saveGooglePayEligibility(bool $isGooglePayEligibility): void { if ($this->isSandbox()) { diff --git a/src/Service/StaticContent.php b/src/Service/StaticContent.php index 8696f27c..5c23bd3a 100644 --- a/src/Service/StaticContent.php +++ b/src/Service/StaticContent.php @@ -103,19 +103,20 @@ protected function createPaymentMethod(string $paymentId, array $definitions): v } } - /** - * Try to load payment model based on given id an set payment inactive - * - * @param string $paymentId - * @return void - * @throws \Exception - */ - protected function deactivatePaymentMethod(string $paymentId) : void { - $paymentModel = oxNew(EshopModelPayment::class); - if ($paymentModel->load($paymentId)) { - $paymentModel->oxpayments__oxactive = new Field(false); - $paymentModel->save(); + protected function reActivatePaymentMethod(string $paymentId): void + { + $activePayments = $this->moduleSettings->getActivePayments(); + if (!in_array($paymentId, $activePayments, true)) { + return; } + + /** @var EshopModelPayment $paymentModel */ + $paymentModel = oxNew(EshopModelPayment::class); + $paymentModel->load($paymentId); + + $paymentModel->oxpayments__oxactive = new Field(true); + + $paymentModel->save(); } /** From c1b4a76279ee1afbbac31848f8443445a7d42b9d Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 15:00:45 +0200 Subject: [PATCH 184/265] use central encoded Shopname --- src/Controller/ProxyController.php | 12 +++--------- src/Core/Api/VaultingService.php | 11 +++++++---- src/Core/OrderRequestFactory.php | 13 ++++++++----- src/Service/ModuleSettings.php | 5 +++++ 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 411ff0b1..68957d83 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -11,15 +11,12 @@ use OxidEsales\Eshop\Application\Component\UserComponent; use OxidEsales\Eshop\Application\Controller\FrontendController; use OxidEsales\Eshop\Application\Model\Address; -use OxidEsales\Eshop\Application\Model\Basket; use OxidEsales\Eshop\Application\Model\DeliverySetList; use OxidEsales\Eshop\Core\Exception\ArticleInputException; use OxidEsales\Eshop\Core\Exception\NoArticleException; use OxidEsales\Eshop\Core\Exception\OutOfStockException; use OxidEsales\Eshop\Core\Exception\StandardException; -use OxidEsales\Eshop\Core\Price; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Core\Api\VaultingService; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface; use OxidSolutionCatalysts\PayPal\Module; @@ -33,16 +30,13 @@ use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; +use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiOrder; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Payer; use OxidSolutionCatalysts\PayPalApi\Model\Orders\PurchaseUnitRequest; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable3; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\Phone as ApiModelPhone; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\PhoneWithType; -use OxidSolutionCatalysts\PayPalApi\Model\Orders\ShippingDetail; /** * Server side interface for PayPal smart buttons. @@ -488,7 +482,7 @@ protected function getRequestedPayPalPaymentId( public function getPaymentRequestLines() { - + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); try { $basket = Registry::getSession()->getBasket(); if ($basket->getItemsCount() === 0) { @@ -508,7 +502,7 @@ public function getPaymentRequestLines() $paymentRequest = [ 'total' => [ - 'label' => Registry::getConfig()->getActiveShop()->getFieldData('oxname'), + 'label' => $moduleSettings->getShopName(), 'amount' => (float)$basket->getBruttoSum(), 'type' => 'final' ], diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index dc20d0f5..bec12806 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -13,11 +13,15 @@ use OxidEsales\Eshop\Core\Registry; use OxidEsales\Eshop\Core\ViewConfig; use OxidSolutionCatalysts\PayPal\Core\Constants; +use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Service\BaseService; class VaultingService extends BaseService { + use ServiceContainer; + public function generateUserIdToken($payPalCustomerId = false): array { $headers = []; @@ -87,6 +91,7 @@ public function createVaultSetupToken(bool $card = false): array */ public function getPaymentSourceForVaulting(bool $card): array { + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $viewConf = Registry::get(ViewConfig::class); $config = Registry::getConfig(); $user = $viewConf->getUser(); @@ -100,13 +105,11 @@ public function getPaymentSourceForVaulting(bool $card): array $user->getFieldData('oxcountryid') ); - $shopName = Registry::getConfig()->getActiveShop()->getFieldData('oxname'); + $shopName = $moduleSettings->getShopName(); $lang = Registry::getLang(); $description = sprintf($lang->translateString('OSC_PAYPAL_DESCRIPTION'), $shopName); - $activeShop = Registry::getConfig()->getActiveShop(); - $name = $user->getFieldData("oxfname"); $name .= $user->getFieldData("oxlname"); $address = [ @@ -122,7 +125,7 @@ public function getPaymentSourceForVaulting(bool $card): array . '-' . strtoupper($country->oxcountry__oxisoalpha2->value); $experience_context = [ - "brand_name" => $activeShop->getFieldData('oxname'), + "brand_name" => $shopName, "locale" => $locale, "return_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', "cancel_url" => $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index f2fca39a..c70e511b 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -122,7 +122,7 @@ public function getRequest( ); //find out which payment token was selected by getting the index via request param $paymentType = key($selectedPaymentToken["payment_source"]); - $useCard = $paymentType == "card"; + $useCard = $paymentType === "card"; $this->modifyPaymentSourceForVaulting($request, $useCard); @@ -241,8 +241,9 @@ protected function getApplicationContext( ?string $cancelUrl, ?bool $setProvidedAddress ): OrderApplicationContext { + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $context = new OrderApplicationContext(); - $context->brand_name = Registry::getConfig()->getActiveShop()->getFieldData('oxname'); + $context->brand_name = $moduleSettings->getShopName(); $context->shipping_preference = 'GET_FROM_FILE'; $context->landing_page = 'LOGIN'; if ($userAction) { @@ -269,8 +270,9 @@ protected function getPurchaseUnits( ?string $invoiceId, bool $withArticles = true ): array { + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); $purchaseUnit = new PurchaseUnitRequest(); - $shopName = Registry::getConfig()->getActiveShop()->getFieldData('oxname'); + $shopName = $moduleSettings->getShopName(); $lang = Registry::getLang(); $purchaseUnit->custom_id = $transactionId; @@ -624,6 +626,7 @@ protected function getPayerPhone(): ?PhoneWithType protected function getPuiPaymentSource(): array { $user = $this->basket->getBasketUser(); + $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); // get Billing CountryCode $country = oxNew(Country::class); @@ -659,11 +662,11 @@ protected function getPuiPaymentSource(): array $activeShop = Registry::getConfig()->getActiveShop(); $experienceContext = new ExperienceContext(); - $experienceContext->brand_name = $activeShop->getFieldData('oxname'); + $experienceContext->brand_name = $moduleSettings->getShopName(); $experienceContext->locale = strtolower($payer->address->country_code) . '-' . strtoupper($payer->address->country_code); - $experienceContext->customer_service_instructions[] = $activeShop->getFieldData('oxinfoemail'); + $experienceContext->customer_service_instructions[] = $activeShop->getRawFieldData('oxinfoemail'); $paymentSource->experience_context = $experienceContext; return [PayPalDefinitions::PUI_REQUEST_PAYMENT_SOURCE_NAME => $paymentSource]; diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index aca3cc47..b5f13feb 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -397,6 +397,11 @@ public function getActivePayments(): array return $activePayments ?: []; } + public function getShopName(): string + { + return Registry::getConfig()->getActiveShop()->getRawFieldData('oxname'); + } + /** * @throws ModuleSettingNotFountException */ From 1d6d74ce7d91e83f43912e21acf69c8f3437470a Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 15:03:46 +0200 Subject: [PATCH 185/265] provide correct encoded Shopname to PayPal --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f344f19d..eb19ccd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### FIX - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders +- provide correct encoded Shopname to PayPal ## [2.5.0] - 2024-08-16 From 1858ba11df02b49ac70922fed2fba49378531b1f Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 15:09:20 +0200 Subject: [PATCH 186/265] Fix order of closing brackets in applepay-template --- CHANGELOG.md | 1 + views/smarty/frontend/blocks/applepay.tpl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb19ccd9..2c07b629 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders - provide correct encoded Shopname to PayPal +- Fix order of closing brackets in applepay-template ## [2.5.0] - 2024-08-16 diff --git a/views/smarty/frontend/blocks/applepay.tpl b/views/smarty/frontend/blocks/applepay.tpl index 10047e65..19ecc398 100644 --- a/views/smarty/frontend/blocks/applepay.tpl +++ b/views/smarty/frontend/blocks/applepay.tpl @@ -69,7 +69,8 @@ [{if $config->isSandbox()}] console.log('Payment Request Data:', globalPaymentRequestData); console.log('--- End preloadPaymentRequestData ---'); - } [{/if}] + [{/if}] + } // Function to handle closing alerts const handle_close = (event) => { From a627a68e6e7acba3f29b258fa7b172783baebfa1 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 12:28:16 +0200 Subject: [PATCH 187/265] also Handling for temp-order with OrderNumber Temporary orders that are no longer needed and already have an order number will be cancelled. Temporary orders without an order number will still be deleted --- CHANGELOG.md | 1 + src/Service/Payment.php | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c07b629..85a8bd98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders - provide correct encoded Shopname to PayPal - Fix order of closing brackets in applepay-template +- Temporary orders that are no longer needed and already have an order number will be cancelled. Temporary orders without an order number will still be deleted ## [2.5.0] - 2024-08-16 diff --git a/src/Service/Payment.php b/src/Service/Payment.php index ed49c8c6..edbeecf0 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -500,14 +500,20 @@ public function removeTemporaryOrder(): void $orderModel->load($sessionOrderId); if ( - $orderModel->isLoaded() && - !$orderModel->hasOrderNumber() + $orderModel->isLoaded() ) { - $orderModel->delete(); + $orderModel->cancelOrder(); $this->logger->log('debug', sprintf( - 'Temporary order without Order number and with id %s was deleted', + 'Temporary order with id %s was canceled', $sessionOrderId )); + if (!$orderModel->hasOrderNumber()) { + $orderModel->delete(); + $this->logger->log('debug', sprintf( + 'Temporary order without Order number and with id %s was deleted', + $sessionOrderId + )); + } } PayPalSession::unsetPayPalOrderId(); From 4950897b65a71a9c0aa96691392b12c0824b5903 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Fri, 30 Aug 2024 14:21:30 +0200 Subject: [PATCH 188/265] CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85a8bd98..563dc9bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### FIX +- [0007711](https://bugs.oxid-esales.com/view.php?id=7711): Temporary orders that are no longer needed and already have an order number will be cancelled. Temporary orders without an order number will still be deleted - [0007713](https://bugs.oxid-esales.com/view.php?id=7713): Correct SQL for select temporary Orders - provide correct encoded Shopname to PayPal - Fix order of closing brackets in applepay-template From eecd7ce31359f1177c900e8661f27205d1eb6735 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 29 Aug 2024 17:07:02 +0200 Subject: [PATCH 189/265] provide BN-Codes on all places --- src/Controller/OrderController.php | 2 ++ src/Controller/ProxyController.php | 6 +++++- src/Core/Api/VaultingService.php | 13 ++++++++++--- src/Core/Webhook/EventVerifier.php | 6 +++++- .../Handler/PaymentCaptureCompletedHandler.php | 7 ++++++- src/Model/Order.php | 6 +++++- src/Service/Payment.php | 9 +++++++-- 7 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index a431f7fe..1e7dde6c 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -284,6 +284,7 @@ public function captureGooglePayOrder(): void $checkoutOrderId, $request, '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); @@ -449,6 +450,7 @@ public function captureApplePayOrder() $orderId, $request, '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (ApiException $exception) { $logger = $this->getServiceFromContainer(Logger::class); diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 68957d83..8322b8c1 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -295,7 +295,11 @@ public function approveOrder() $service = $serviceFactory->getOrderService(); try { - $response = $service->showOrderDetails($orderId, ''); + $response = $service->showOrderDetails( + $orderId, + '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + ); } catch (Exception $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); diff --git a/src/Core/Api/VaultingService.php b/src/Core/Api/VaultingService.php index bec12806..ad9c88a6 100644 --- a/src/Core/Api/VaultingService.php +++ b/src/Core/Api/VaultingService.php @@ -201,9 +201,13 @@ public function getVaultPaymentTokens($paypalCustomerId) return null; } + $headers = []; + $headers['Content-Type'] = 'application/x-www-form-urlencoded'; + $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; + $path = '/v3/vault/payment-tokens?customer_id=' . $paypalCustomerId; - $response = $this->send('GET', $path); + $response = $this->send('GET', $path, [], $headers); $body = $response->getBody(); return json_decode((string)$body, true); @@ -222,11 +226,14 @@ public function getVaultPaymentTokenByIndex($paypalCustomerId, $index) */ public function deleteVaultedPayment($paymentTokenId) { + $headers = []; + $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; + $path = '/v3/vault/payment-tokens/' . $paymentTokenId; - $response = $this->send('DELETE', $path); + $response = $this->send('DELETE', $path, [], $headers); - return $response->getStatusCode() == 204; + return $response->getStatusCode() === 204; } /** diff --git a/src/Core/Webhook/EventVerifier.php b/src/Core/Webhook/EventVerifier.php index ed3e4224..dce3a9c7 100644 --- a/src/Core/Webhook/EventVerifier.php +++ b/src/Core/Webhook/EventVerifier.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook; use OxidEsales\Eshop\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; use OxidSolutionCatalysts\PayPalApi\Service\GenericService; use OxidSolutionCatalysts\PayPal\Core\Config; @@ -60,9 +61,12 @@ public function verify(array $headers, string $body): bool 'webhook_event' => $normalizedBody ]; + $headers = []; + $headers['PayPal-Partner-Attribution-Id'] = Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP; + /** @var GenericService $notificationService */ $notificationService = Registry::get(ServiceFactory::class)->getNotificationService(); - $response = $notificationService->request('POST', $payload); + $response = $notificationService->request('POST', $payload, [], $headers); if ( !$response['verification_status'] || ( diff --git a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php index 931dff65..b80ea715 100644 --- a/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php +++ b/src/Core/Webhook/Handler/PaymentCaptureCompletedHandler.php @@ -8,6 +8,7 @@ namespace OxidSolutionCatalysts\PayPal\Core\Webhook\Handler; use OxidEsales\EshopCommunity\Core\Registry; +use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; @@ -39,7 +40,11 @@ protected function getPayPalOrderDetails(string $payPalOrderId): ?PayPalApiModel try { $apiOrder = Registry::get(ServiceFactory::class) ->getOrderService() - ->showOrderDetails($payPalOrderId, ''); + ->showOrderDetails( + $payPalOrderId, + '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + ); } catch (ApiException $exception) { /** @var Logger $logger */ $logger = $this->getServiceFromContainer(Logger::class); diff --git a/src/Model/Order.php b/src/Model/Order.php index f5b53d08..33e810e5 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -338,7 +338,11 @@ public function getPayPalCheckoutOrder($payPalOrderId = ''): PayPalApiOrder if (!$this->payPalApiOrder) { /** @var Orders $orderService */ $orderService = Registry::get(ServiceFactory::class)->getOrderService(); - $this->payPalApiOrder = $orderService->showOrderDetails($payPalOrderId, ''); + $this->payPalApiOrder = $orderService->showOrderDetails( + $payPalOrderId, + '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + ); } return $this->payPalApiOrder; diff --git a/src/Service/Payment.php b/src/Service/Payment.php index edbeecf0..927f2e02 100644 --- a/src/Service/Payment.php +++ b/src/Service/Payment.php @@ -337,7 +337,8 @@ public function doCapturePayPalOrder( '', $checkoutOrderId, $request, - '' + '', + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP ); } catch (ApiException $exception) { $this->handlePayPalApiError($exception); @@ -768,7 +769,11 @@ public function fetchOrderFields(string $paypalOrderId, string $fields = ''): Ap { return $this->serviceFactory ->getOrderService() - ->showOrderDetails($paypalOrderId, $fields); + ->showOrderDetails( + $paypalOrderId, + $fields, + Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP + ); } /** From 348a3ede603eac0a743fc4fb271c353b4a5eaf1c Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Thu, 29 Aug 2024 17:11:40 +0200 Subject: [PATCH 190/265] new Version & Changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 563dc9bf..b61ea3f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - provide correct encoded Shopname to PayPal - Fix order of closing brackets in applepay-template - Temporary orders that are no longer needed and already have an order number will be cancelled. Temporary orders without an order number will still be deleted +- Provide BN codes even to previously overlooked API calls ## [2.5.0] - 2024-08-16 From a5c57e1205530c4146d8edef8a60eeaffe2334fc Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:36:30 +0000 Subject: [PATCH 191/265] Update tag to v2.0.16 --- LATEST_CLIENT_TAG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LATEST_CLIENT_TAG b/LATEST_CLIENT_TAG index a0252245..3a3b26ea 100644 --- a/LATEST_CLIENT_TAG +++ b/LATEST_CLIENT_TAG @@ -1 +1 @@ -v2.0.15 \ No newline at end of file +v2.0.16 \ No newline at end of file From 2a07d22c7b00f75f1b49fda59bd129278ee4934d Mon Sep 17 00:00:00 2001 From: Lars Stegelitz Date: Fri, 6 Sep 2024 17:20:26 +0200 Subject: [PATCH 192/265] PSPAYPAL-833 fixed missing method "getShopName()" plus using a backwards compatible way to access raw data --- src/Service/ModuleSettings.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index b5f13feb..ddd2d95e 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -11,6 +11,7 @@ use OxidEsales\Eshop\Application\Model\Country; use OxidEsales\Eshop\Application\Model\Payment; +use OxidEsales\Eshop\Application\Model\Shop; use OxidEsales\Eshop\Application\Model\User; use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Framework\Module\Configuration\Bridge\ModuleConfigurationDaoBridgeInterface; @@ -399,7 +400,19 @@ public function getActivePayments(): array public function getShopName(): string { - return Registry::getConfig()->getActiveShop()->getRawFieldData('oxname'); + $value = 'OXID-eSales Shop without name'; + /** @var Shop $shop */ + $shop = Registry::getConfig()->getActiveShop(); + if (isset($shop->oxshops__oxname->rawValue)) { + $value = $shop->oxshops__oxname->rawValue; + } + elseif(isset($shop->oxshops__oxname->value)) { + $value = $shop->oxshops__oxname->value; + } + return $value; + + // method "getRawFieldData" available only with shop v6.5+ + //return Registry::getConfig()->getActiveShop()->getRawFieldData('oxname'); } /** From 37aeac5f964db9fb6eb99fac6fc582a39028ca6a Mon Sep 17 00:00:00 2001 From: Lars Stegelitz Date: Fri, 6 Sep 2024 17:30:09 +0200 Subject: [PATCH 193/265] PSPAYPAL-833 replace another getRawFieldData with backward compatible variant --- src/Core/OrderRequestFactory.php | 2 +- src/Service/ModuleSettings.php | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index c70e511b..93fcb1e1 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -666,7 +666,7 @@ protected function getPuiPaymentSource(): array $experienceContext->locale = strtolower($payer->address->country_code) . '-' . strtoupper($payer->address->country_code); - $experienceContext->customer_service_instructions[] = $activeShop->getRawFieldData('oxinfoemail'); + $experienceContext->customer_service_instructions[] = $moduleSettings->getInfoEMail(); $paymentSource->experience_context = $experienceContext; return [PayPalDefinitions::PUI_REQUEST_PAYMENT_SOURCE_NAME => $paymentSource]; diff --git a/src/Service/ModuleSettings.php b/src/Service/ModuleSettings.php index ddd2d95e..c3ffa80b 100755 --- a/src/Service/ModuleSettings.php +++ b/src/Service/ModuleSettings.php @@ -400,7 +400,7 @@ public function getActivePayments(): array public function getShopName(): string { - $value = 'OXID-eSales Shop without name'; + $value = ''; /** @var Shop $shop */ $shop = Registry::getConfig()->getActiveShop(); if (isset($shop->oxshops__oxname->rawValue)) { @@ -415,6 +415,20 @@ public function getShopName(): string //return Registry::getConfig()->getActiveShop()->getRawFieldData('oxname'); } + public function getInfoEMail(): string + { + $value = ''; + /** @var Shop $shop */ + $shop = Registry::getConfig()->getActiveShop(); + if (isset($shop->oxshops__oxinfoemail->rawValue)) { + $value = $shop->oxshops__oxinfoemail->rawValue; + } + elseif(isset($shop->oxshops__oxinfoemail->value)) { + $value = $shop->oxshops__oxinfoemail->value; + } + return $value; + } + /** * @throws ModuleSettingNotFountException */ From 089cab08eecee8ec02c5e7bc2b0de1703d0a6080 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 3 Sep 2024 15:43:18 +0200 Subject: [PATCH 194/265] fix Check if user exists, then getFieldData --- src/Core/OrderRequestFactory.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Core/OrderRequestFactory.php b/src/Core/OrderRequestFactory.php index 93fcb1e1..5fde2947 100644 --- a/src/Core/OrderRequestFactory.php +++ b/src/Core/OrderRequestFactory.php @@ -754,7 +754,7 @@ private function getVaultingService() private function getUsersPayPalCustomerId() { - $config = Registry::getConfig(); - return $config->getUser()->getFieldData("oscpaypalcustomerid"); + $user = Registry::getConfig()->getUser(); + return $user ? $user->getFieldData("oscpaypalcustomerid") : ''; } } From c4f451f5612c58060cf5deaa31e1d004e7987bc5 Mon Sep 17 00:00:00 2001 From: Mario Lorenz Date: Tue, 3 Sep 2024 15:45:04 +0200 Subject: [PATCH 195/265] use only one SDK-URL for all and move showPayPalExpressInMiniBasket to viewConfig --- src/Core/ViewConfig.php | 143 ++++++++---------- .../frontend/blocks/layout/base__base_js.tpl | 34 ++--- 2 files changed, 78 insertions(+), 99 deletions(-) diff --git a/src/Core/ViewConfig.php b/src/Core/ViewConfig.php index 3820c1ef..c4d775b6 100644 --- a/src/Core/ViewConfig.php +++ b/src/Core/ViewConfig.php @@ -99,6 +99,11 @@ public function getIsVaultingActive(): bool return $this->getServiceFromContainer(ModuleSettings::class)->getIsVaultingActive(); } + public function isVaultingEligibility(): bool + { + return $this->getServiceFromContainer(ModuleSettings::class)->isVaultingEligibility(); + } + /** * @return Config */ @@ -158,12 +163,32 @@ public function getPayPalJsSdkUrl(): string { $config = Registry::getConfig(); $lang = Registry::getLang(); + $params = []; + $enableFunding = []; + $disableFunding = [ + 'bancontact', + 'blik', + 'eps', + 'giropay', + 'ideal', + 'mercadopago', + 'p24', + 'venmo', + ]; + $components = [ + 'buttons', + 'googlepay', + 'applepay', + ]; + + if ($this->getTopActiveClassName() !== 'payment') { + $disableFunding[] = 'sepa'; + } $localeCode = $this->getServiceFromContainer(LanguageLocaleMapper::class) ->mapLanguageToLocale($lang->getLanguageAbbr()); $moduleSettings = $this->getServiceFromContainer(ModuleSettings::class); - $params = []; $params['client-id'] = $this->getPayPalClientId(); $params['integration-date'] = Constants::PAYPAL_INTEGRATION_DATE; @@ -174,83 +199,34 @@ public function getPayPalJsSdkUrl(): string $params['currency'] = strtoupper($currency->name); } - $params['components'] = 'buttons,googlepay'; $params['merchant-id'] = $moduleSettings->getMerchantId(); - // Available components: enable messages+buttons for PDP + if ($this->isPayPalBannerActive()) { - $params['components'] .= ',messages'; + $components[] = 'messages'; } - $params['components'] .= ',applepay'; + if ($moduleSettings->showPayPalPayLaterButton()) { - $params['enable-funding'] = 'paylater'; + $enableFunding[] = 'paylater'; } - $params['disable-funding'] = 'sepa,bancontact,blik,eps,giropay,ideal,mercadopago,p24,venmo'; - if ($moduleSettings->isAcdcEligibility()) { - $params['disable-funding'] .= ',card'; + $components[] = 'hosted-fields'; } else { - if (isset($params['enable-funding'])) { - $params['enable-funding'] .= ',card'; - } else { - $params['enable-funding'] = 'card'; - } + $enableFunding[] = 'card'; } - $params['locale'] = $localeCode; - - return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); - } - - /** - * Gets PayPal JS SDK url for ACDC - * - * @return string - */ - public function getPayPalJsSdkUrlForACDC(): string - { - return $this->getBasePayPalJsSdkUrl('hosted-fields'); - } - - /** - * Gets PayPal JS SDK url for Button Payments like SEPA and CreditCardFallback - * - * @return string - */ - public function getPayPalJsSdkUrlForButtonPayments(): string - { - return $this->getBasePayPalJsSdkUrl('funding-eligibility', true); - } - - protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): string - { - $config = Registry::getConfig(); - $lang = Registry::getLang(); - - $localeCode = $this->getServiceFromContainer(LanguageLocaleMapper::class) - ->mapLanguageToLocale($lang->getLanguageAbbr()); - - $params = []; - $params['client-id'] = $this->getPayPalClientId(); - $params['integration-date'] = Constants::PAYPAL_INTEGRATION_DATE; - - if ($currency = $config->getActShopCurrencyObject()) { - $params['currency'] = strtoupper($currency->name); + if ($this->getIsVaultingActive()) { + $components[] = 'card-fields'; } - if ($continueFlow) { - $params['intent'] = strtolower(Constants::PAYPAL_ORDER_INTENT_CAPTURE); - $params['commit'] = 'true'; + if ($components) { + $params['components'] = implode(',', $components); } - - $params['components'] = 'buttons,googlepay,' . $type; - - if ($this->isPayPalBannerActive()) { - $params['components'] .= ',messages'; + if ($enableFunding) { + $params['enable-funding'] = implode(',', $enableFunding); } - - if ($this->getIsVaultingActive()) { - $params['components'] .= ',card-fields'; + if ($disableFunding) { + $params['disable-funding'] = implode(',', $disableFunding); } $params['locale'] = $localeCode; @@ -258,6 +234,33 @@ protected function getBasePayPalJsSdkUrl($type = '', $continueFlow = false): str return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); } + public function showPayPalExpressInMiniBasket(): bool + { + $className = $this->getTopActiveClassName(); + $showButton = false; + $payPalConfig = $this->getPayPalCheckoutConfig(); + $ppActive = $payPalConfig->isActive(); + $configShowMiniBasketButton = $payPalConfig->showPayPalMiniBasketButton(); + $ppExpressSessionActive = $this->isPayPalExpressSessionActive(); + $acdcSessionActive = $this->isPayPalACDCSessionActive(); + if ( + $className !== 'payment' && + $ppActive && + $configShowMiniBasketButton && + !$ppExpressSessionActive && + ( + ( + $className === 'order' && + !$acdcSessionActive + ) || + $className !== 'order' + ) + ) { + $showButton = true; + } + return $showButton; + } + public function getUserIdForVaulting(): string { if (!$this->getUser()) { @@ -334,18 +337,6 @@ public function getPayPalClientId(): string return $this->getServiceFromContainer(ModuleSettings::class)->getClientId(); } - /** - * API URL getter for use with the installment banner feature - */ - public function getPayPalApiBannerUrl(): string - { - $params['client-id'] = $this->getPayPalClientId(); - - $params['components'] = 'messages'; - - return Constants::PAYPAL_JS_SDK_URL . '?' . http_build_query($params); - } - /** * API ID getter for use with the installment banner feature */ diff --git a/views/smarty/frontend/blocks/layout/base__base_js.tpl b/views/smarty/frontend/blocks/layout/base__base_js.tpl index 91418182..0f2c394d 100644 --- a/views/smarty/frontend/blocks/layout/base__base_js.tpl +++ b/views/smarty/frontend/blocks/layout/base__base_js.tpl @@ -1,30 +1,18 @@ [{$smarty.block.parent}] [{if $oViewConf->isPayPalCheckoutActive()}] [{assign var="className" value=$oViewConf->getTopActiveClassName()}] - [{if $oViewConf->isPayPalExpressPaymentEnabled() && - (($className == 'order' && !$oViewConf->isPayPalACDCSessionActive()) || ($className !== 'order' && $className !== 'payment')) && - ( - ($oxcmp_basket->getProductsCount() && $oViewConf->showPayPalMiniBasketButton()) || - ($className == 'details' && $oViewConf->showPayPalProductDetailsButton()) || - ($className == 'basket' && $oViewConf->showPayPalBasketButton()) - ) - && ($className !== 'oscaccountvaultcard') && ($className !== 'oscaccountvault') - }] - - [{assign var="sCountryRestriction" value=$oViewConf->getCountryRestrictionForPayPalExpress()}] - [{if $sCountryRestriction}] - + - [{elseif $className == 'payment' || $className == 'oscaccountvaultcard'}] - - [{elseif $className == 'oscaccountvault'}] - - [{elseif $oViewConf->isPayPalBannerActive() && ($className == 'start' || $className == 'search' || $className == 'details' || $className == 'alist' || $className == 'basket')}] - + data-partner-attribution-id="[{$oViewConf->getPayPalPartnerAttributionIdForBanner()}]" + data-client-token="[{$oViewConf->getDataClientToken()}]" + > + [{assign var="sCountryRestriction" value=$oViewConf->getCountryRestrictionForPayPalExpress()}] + [{if $sCountryRestriction}] + [{/if}] [{if $submitCart}] + + {% set sCountryRestriction = oViewConf.getCountryRestrictionForPayPalExpress() %} {% if sCountryRestriction %} + +{% endhasrights %} \ No newline at end of file From 107dee784dc34ae10292a210d824ae4ba8af0905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Gust?= Date: Tue, 3 Dec 2024 19:14:19 +0100 Subject: [PATCH 227/265] PSPAYPAL-815 add first working version for google pay in oxid 7 version --- assets/css/paypal.css | 16 +-- assets/js/paypal-frontend.min.js | 1 + .../build/js/paypal-frontend-googlepay.js | 52 ++++--- resources/build/scss/paypal.scss | 18 +-- resources/grunt/sass.js | 4 +- src/Controller/OrderController.php | 134 ++++-------------- src/Controller/ProxyController.php | 19 ++- .../GooglePay/GooglePayPayPalService.php | 33 +++++ src/Service/HateoasLinkService.php | 22 ++- src/Service/OrderPayPalService.php | 28 ++++ src/Service/PayPalUrlService.php | 26 ++++ .../themes/default/layout/base.html.twig | 6 +- .../default/page/checkout/order.html.twig | 17 +-- .../twig/frontend/googlepay_button.html.twig | 10 +- 14 files changed, 186 insertions(+), 200 deletions(-) create mode 100644 assets/js/paypal-frontend.min.js create mode 100644 src/Service/GooglePay/GooglePayPayPalService.php create mode 100644 src/Service/OrderPayPalService.php create mode 100644 src/Service/PayPalUrlService.php diff --git a/assets/css/paypal.css b/assets/css/paypal.css index 93908fc1..e189f3f7 100644 --- a/assets/css/paypal.css +++ b/assets/css/paypal.css @@ -1,15 +1 @@ -.paypal-button-or { - padding: 10px; } - -.paypal-button-wrapper { - width: 100%; } - .paypal-button-wrapper.large { - max-width: 250px; } - .paypal-button-wrapper.small { - max-height: 200px; } -#paypal-installment-banner-container>SPAN { - margin: 0 auto; -} -.paypal-sepa-option-info { - margin-top: 10px; -} \ No newline at end of file +.google-pay-loading-container{float:right;margin-right:calc(50%)}#oscpaypal_googlepay{float:right} diff --git a/assets/js/paypal-frontend.min.js b/assets/js/paypal-frontend.min.js new file mode 100644 index 00000000..bf33200a --- /dev/null +++ b/assets/js/paypal-frontend.min.js @@ -0,0 +1 @@ +window.OxidPayPal={sdkLoaded:!1,onSDKLoaded:function(){this.sdkLoaded=!0},isSDKLoaded:function(){return this.sdkLoaded}},window.OxidPayPalGooglePay={baseRequest:{apiVersion:2,apiVersionMinor:0},paymentsClient:null,allowedPaymentMethods:null,merchantInfo:null,googlePayContainer:null,buttonId:null,token:null,selfLink:null,useGooglePayAddress:null,isSandbox:null,merchantName:null,totalPrice:null,currency:null,deliveryAddressMD5:null,language:null,loadingContainer:null,init:async function(){var e;this.googlePayContainer=document.getElementById("oscpaypal_googlepay"),this.googlePayContainer&&(this.buttonId=this.googlePayContainer.dataset.buttonId,this.token=this.googlePayContainer.dataset.token,this.selfLink=this.googlePayContainer.dataset.selfLink,this.useGooglePayAddress=!!Number(this.googlePayContainer.dataset.useGooglePayAddress),this.isSandbox=!!Number(this.googlePayContainer.dataset.isSandbox),this.merchantName=this.googlePayContainer.dataset.merchantName,this.totalPrice=this.googlePayContainer.dataset.totalPrice,this.currency=this.googlePayContainer.dataset.currency,this.deliveryAddressMD5=this.googlePayContainer.dataset.deliveryAddressMd5,this.language=this.googlePayContainer.dataset.language,e=document.getElementsByClassName(this.googlePayContainer.dataset.loadingContainerClassName),this.loadingContainer=e[0],await window.googlePayReady,this.onGooglePayLoaded())},getGoogleIsReadyToPayRequest:function(e){return Object.assign({},this.baseRequest,{allowedPaymentMethods:e})},getGooglePayConfig:async function(){var e;return null!=this.allowedPaymentMethods&&null!=this.merchantInfo||(e=await paypal.Googlepay().config(),this.allowedPaymentMethods=e.allowedPaymentMethods,this.merchantInfo=e.merchantInfo,this.merchantInfo.merchantName=this.merchantName),{allowedPaymentMethods:this.allowedPaymentMethods,merchantInfo:this.merchantInfo}},getGooglePaymentDataRequest:async function(){const e=Object.assign({},this.baseRequest);var{allowedPaymentMethods:t,merchantInfo:a}=await this.getGooglePayConfig();return e.transactionInfo=this.getGoogleTransactionInfo(),e.allowedPaymentMethods=t,e.merchantInfo=a,e.callbackIntents=["PAYMENT_AUTHORIZATION"],e.emailRequired=!0,e.shippingAddressRequired=this.useGooglePayAddress,e.shippingAddressParameters={phoneNumberRequired:!0},e},onPaymentAuthorized:function(a){return new Promise(function(t,e){this.processPayment(a).then(function(e){t({transactionState:"SUCCESS"})}).catch(function(e){t({transactionState:"ERROR"})})}.bind(this))},getGooglePaymentsClient:function(){return null===this.paymentsClient&&(this.paymentsClient=new google.payments.api.PaymentsClient({environment:this.isSandbox?"TEST":"PRODUCTION",paymentDataCallbacks:{onPaymentAuthorized:this.onPaymentAuthorized.bind(this)}})),this.paymentsClient},onGooglePayLoaded:async function(){if(window.OxidPayPal&&window.OxidPayPal.isSDKLoaded()){const t=this.getGooglePaymentsClient();var e=(await this.getGooglePayConfig())["allowedPaymentMethods"];t.isReadyToPay(this.getGoogleIsReadyToPayRequest(e)).then(function(e){e.result&&(this.loadingContainer.style.display="none",this.addGooglePayButton())}.bind(this)).catch(function(e){console.error(e)})}else window.setTimeout(this.onGooglePayLoaded.bind(this),500)},addGooglePayButton:function(){const e=this.getGooglePaymentsClient();var t=e.createButton({buttonType:"buy",buttonLocale:this.language,onClick:this.onGooglePaymentButtonClicked.bind(this)});document.getElementById("oscpaypal_googlepay").appendChild(t)},getGoogleTransactionInfo:function(){return{currencyCode:this.currency,totalPriceStatus:"FINAL",totalPrice:this.totalPrice,totalPriceLabel:"Total"}},onGooglePaymentButtonClicked:async function(){const e=await this.getGooglePaymentDataRequest(),t=(e.transactionInfo=this.getGoogleTransactionInfo(),this.getGooglePaymentsClient());t.loadPaymentData(e)},processPayment:async function(e){try{var t=this.selfLink+"&cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&stoken="+this.token,{id:a,status:n,links:o}=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then(e=>e.json());const s=new OxidPayPalHateoasLinks;var i=s.getApproveLink(o);if(i)window.location.href=i;else{if("APPROVED"===n)return this.captureOrder(a),{transactionState:"SUCCESS"};if("PAYER_ACTION_REQUIRED"!==n)return console.error("Payment was not approved"),{transactionState:"ERROR"};console.log("==== Confirm Payment Completed Payer Action Required ====="),this.googlePayUserActionRequired(a)}}catch(e){return{transactionState:"ERROR",error:{message:e.message}}}},googlePayUserActionRequired:function(e){paypal.Googlepay().initiatePayerAction({orderId:e}).then(async()=>{console.log("===== Payer Action Completed ====="),await this.createOxidOrder(e)})},createOxidOrder:async function(e){var t=this.selfLink+"&cl=order&fnc=createGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5;(createData=new FormData).append("orderID",e),fetch(t,{method:"POST",body:createData}).then(function(e){return e.json()}).then(function(e){"ERROR"===e.status&&location.reload()})},captureOrder:async function(e){(captureData=new FormData).append("orderID",e);await fetch(this.selfLink+"&cl=order&fnc=captureGooglePayOrder&context=continue&stoken="+this.token+"&sDeliveryAddressMD5="+this.deliveryAddressMD5,{method:"post",body:captureData}).then(function(e){return e.json()}).then(function(e){console.log("==== Capture Order Completed ====");var t=Array.isArray(e.location)&&e.location[0];window.location.href=this.selfLink+t,"ERROR"===e.status&&location.reload()}.bind(this)).catch(e=>{console.error(e)})}},OxidPayPalGooglePay.init(),window.OxidPayPalGooglePay3DS={handle:async e=>{var t={...await window.OxidPayPalGooglePay.getGooglePaymentDataRequest(),paymentData:{tokenizationData:{type:"PAYMENT_GATEWAY",token:e.id},threeDSData:{authenticationParameters:{threeDSRequestData:{threeDSServerTransID:generateTransactionId(),challengeWindowSize:"03",messageCategory:"PAYMENT_AUTHENTICATION"}}}}};try{await paymentClient.loadPaymentData(t);if((await fetch("/v2/checkout/orders/"+e.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify([{op:"replace",path:"/payment_source/google_pay/card/authentication_result",value:{liability_shift:"POSSIBLE",three_d_secure:{authentication_status:"Y",enrollment_status:"Y"}}}])})).ok)return await fetch(`/v2/checkout/orders/${e.id}/capture`,{method:"POST"})}catch(e){throw console.error("3DS Authentication failed:",e),e}}},function(){"use strict";function e(){}e.prototype.getApproveLink=function(e){e=e.find(e=>"approve"===e.rel);return e?e.href:null},window.OxidPayPalHateoasLinks=e}(); \ No newline at end of file diff --git a/resources/build/js/paypal-frontend-googlepay.js b/resources/build/js/paypal-frontend-googlepay.js index f84fa286..71c73e27 100644 --- a/resources/build/js/paypal-frontend-googlepay.js +++ b/resources/build/js/paypal-frontend-googlepay.js @@ -17,6 +17,8 @@ window.OxidPayPalGooglePay = { totalPrice: null, currency: null, deliveryAddressMD5: null, + language: null, + loadingContainer: null, init: async function () { this.googlePayContainer = document.getElementById('oscpaypal_googlepay'); if (this.googlePayContainer) { @@ -25,10 +27,13 @@ window.OxidPayPalGooglePay = { this.selfLink = this.googlePayContainer.dataset.selfLink; this.useGooglePayAddress = !!Number(this.googlePayContainer.dataset.useGooglePayAddress); this.isSandbox = !!Number(this.googlePayContainer.dataset.isSandbox); - this.merchantName = !!Number(this.googlePayContainer.dataset.merchantName); + this.merchantName = this.googlePayContainer.dataset.merchantName; this.totalPrice = this.googlePayContainer.dataset.totalPrice; this.currency = this.googlePayContainer.dataset.currency; this.deliveryAddressMD5 = this.googlePayContainer.dataset.deliveryAddressMd5; + this.language = this.googlePayContainer.dataset.language; + let elements = document.getElementsByClassName(this.googlePayContainer.dataset.loadingContainerClassName); + this.loadingContainer = elements[0]; await window.googlePayReady; this.onGooglePayLoaded(); @@ -36,7 +41,7 @@ window.OxidPayPalGooglePay = { }, getGoogleIsReadyToPayRequest: function (allowedPaymentMethods) { return Object.assign({}, this.baseRequest, { - allowedPaymentMethods: allowedPaymentMethods, + allowedPaymentMethods: allowedPaymentMethods }); }, @@ -46,6 +51,7 @@ window.OxidPayPalGooglePay = { const googlePayConfig = await paypal.Googlepay().config(); this.allowedPaymentMethods = googlePayConfig.allowedPaymentMethods; this.merchantInfo = googlePayConfig.merchantInfo; + this.merchantInfo.merchantName = this.merchantName; } return { allowedPaymentMethods: this.allowedPaymentMethods, @@ -57,20 +63,25 @@ window.OxidPayPalGooglePay = { getGooglePaymentDataRequest: async function () { const paymentDataRequest = Object.assign({}, this.baseRequest); const {allowedPaymentMethods, merchantInfo} = await this.getGooglePayConfig(); - paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods; + paymentDataRequest.transactionInfo = this.getGoogleTransactionInfo(); + paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods; paymentDataRequest.merchantInfo = merchantInfo; paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"]; + paymentDataRequest.emailRequired = true; + paymentDataRequest.shippingAddressRequired = this.useGooglePayAddress; + paymentDataRequest.shippingAddressParameters = {'phoneNumberRequired': true}; + return paymentDataRequest; }, onPaymentAuthorized: function (paymentData) { - return new Promise(function (resolve, reject) { + return new Promise(function (resolve) { this.processPayment(paymentData) - .then(function (data) { + .then(function () { resolve({transactionState: "SUCCESS"}); }) - .catch(function (errDetails) { + .catch(function () { resolve({transactionState: "ERROR"}); }); }.bind(this)); @@ -79,7 +90,7 @@ window.OxidPayPalGooglePay = { getGooglePaymentsClient: function () { if (this.paymentsClient === null) { this.paymentsClient = new google.payments.api.PaymentsClient({ - environment: "TEST", + environment: this.isSandbox ? "TEST" : "PRODUCTION", paymentDataCallbacks: { onPaymentAuthorized: this.onPaymentAuthorized.bind(this), }, @@ -95,6 +106,7 @@ window.OxidPayPalGooglePay = { .isReadyToPay(this.getGoogleIsReadyToPayRequest(allowedPaymentMethods)) .then(function (response) { if (response.result) { + this.loadingContainer.style.display = 'none'; this.addGooglePayButton(); } }.bind(this)) @@ -109,6 +121,8 @@ window.OxidPayPalGooglePay = { addGooglePayButton: function () { const paymentsClient = this.getGooglePaymentsClient(); const button = paymentsClient.createButton({ + buttonType: 'buy', + buttonLocale: this.language, onClick: this.onGooglePaymentButtonClicked.bind(this), }); document.getElementById("oscpaypal_googlepay").appendChild(button); @@ -132,7 +146,6 @@ window.OxidPayPalGooglePay = { processPayment: async function (paymentData) { try { - /*** Create oxid Order ***/ const createOrderUrl = this.selfLink + '&cl=oscpaypalproxy&fnc=createGooglepayOrder&paymentid=oscpaypal_googlepay&context=continue&stoken=' + this.token; const {id: orderId, status, links} = await fetch(createOrderUrl, { @@ -166,7 +179,6 @@ window.OxidPayPalGooglePay = { }; } }, - googlePayUserActionRequired: function (orderId) { paypal .Googlepay() @@ -176,14 +188,6 @@ window.OxidPayPalGooglePay = { await this.createOxidOrder(orderId); }); }, - confirnOrder: async function (orderId) { - const {status} = await paypal.Googlepay().confirmOrder({ - orderId: orderId, - paymentMethodData: paymentData.paymentMethodData, - }); - - return status; - }, createOxidOrder: async function (orderId) { const url = this.selfLink + '&cl=order&fnc=createGooglePayOrder&context=continue&stoken=' + this.token + '&sDeliveryAddressMD5=' + this.deliveryAddressMD5; createData = new FormData(); @@ -191,16 +195,8 @@ window.OxidPayPalGooglePay = { fetch(url, { method: 'POST', body: createData - }).then(async function (response) { - if (response.ok) { - const jsonData = await response.json(); - window.location.href = jsonData.approveUrl; - } - // @todo we need to capture the order after the payer action is completed - // await this.captureOrder(orderId); - // console.log(" ===== Order Capture Completed ===== "); - // return {transactionState: "SUCCESS"}; - return response.json(); + }).then(function (res) { + return res.json(); }).then(function (data) { if (data.status === "ERROR") { location.reload(); @@ -210,7 +206,7 @@ window.OxidPayPalGooglePay = { captureOrder: async function (orderId) { captureData = new FormData(); captureData.append('orderID', orderId); - const captureResponse = await fetch(this.selfLink + '&cl=order&fnc=captureGooglePayOrder&context=continue&stoken=' + this.token + '&sDeliveryAddressMD5=' + this.deliveryAddressMD5, { + await fetch(this.selfLink + '&cl=order&fnc=captureGooglePayOrder&context=continue&stoken=' + this.token + '&sDeliveryAddressMD5=' + this.deliveryAddressMD5, { method: 'post', body: captureData }).then(function (res) { diff --git a/resources/build/scss/paypal.scss b/resources/build/scss/paypal.scss index 88f80ce3..5fcec213 100644 --- a/resources/build/scss/paypal.scss +++ b/resources/build/scss/paypal.scss @@ -1,12 +1,8 @@ -.paypal-button-or { - padding: 10px; -} -.paypal-button-wrapper { - width: 100%; - &.large { - max-width: 250px; - } - &.small { - max-width: 200px; - } +.google-pay-loading-container { + float: right; + margin-right: calc(50%); } + +#oscpaypal_googlepay { + float: right; +} \ No newline at end of file diff --git a/resources/grunt/sass.js b/resources/grunt/sass.js index 9a36e6d7..7fcf9113 100644 --- a/resources/grunt/sass.js +++ b/resources/grunt/sass.js @@ -5,7 +5,7 @@ module.exports = { options: { implementation: sass, update: true, - style: 'nested' + outputStyle: 'nested' }, files: { "../assets/css/bootstrap.css": "node_modules/bootstrap/scss/bootstrap.scss", @@ -18,7 +18,7 @@ module.exports = { options: { implementation: sass, update: true, - style: 'compressed' + outputStyle: 'compressed' }, files: { "../assets/css/bootstrap.css": "node_modules/bootstrap/scss/bootstrap.scss", diff --git a/src/Controller/OrderController.php b/src/Controller/OrderController.php index 56205894..7305853c 100644 --- a/src/Controller/OrderController.php +++ b/src/Controller/OrderController.php @@ -12,7 +12,6 @@ use OxidEsales\Eshop\Core\DisplayError; use OxidEsales\Eshop\Core\Exception\StandardException; use OxidEsales\Eshop\Core\Registry; -use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Core\Constants; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; @@ -22,10 +21,12 @@ use OxidSolutionCatalysts\PayPal\Exception\Redirect; use OxidSolutionCatalysts\PayPal\Exception\RedirectWithMessage; use OxidSolutionCatalysts\PayPal\Model\Order as PayPalOrderModel; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; use OxidSolutionCatalysts\PayPal\Service\UserRepository; -use OxidSolutionCatalysts\PayPal\Service\HateoasLinkService; +use OxidSolutionCatalysts\PayPal\Service\GooglePay\GooglePayPayPalService; +use OxidSolutionCatalysts\PayPal\Service\OrderPayPalService; use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Exception\ApiException; @@ -229,57 +230,33 @@ public function createGooglePayOrder(): void $paymentService = $this->getServiceFromContainer(PaymentService::class); $paymentService->removeTemporaryOrder(); Registry::getSession()->setVariable('sess_challenge', $this->getUtilsObjectInstance()->generateUID()); + /** @var Logger $logger */ + $logger = $this->getServiceFromContainer(Logger::class); $_POST['sDeliveryAddressMD5'] = $this->getDeliveryAddressMD5(); - $status = $this->execute(); + $paypalOrderId = Registry::getRequest()->getRequestParameter('token'); + $_POST['orderID'] = $paypalOrderId; + $this->execute(); } catch (Exception $exception) { - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); $this->outputJson(['googlepayerror' => 'failed to execute shop order']); return; } - $response = $this->doCreatePatchedOrder(); - if (!($paypalOrderId = $response['id'])) { - $this->outputJson(['googlepayerror' => 'cannot create paypal order']); - return; - } - - if (!$status) { - $response = ['googlepayerror' => 'unexpected order status ' . $status]; - $paymentService->removeTemporaryOrder(); - } else { - PayPalSession::storePayPalOrderId($paypalOrderId); - $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); - $payPalOrder = $paymentService->getPayPalCheckoutOrder($sessionOrderId, $paypalOrderId); - $payPalOrder->setStatus($response['status']); - $payPalOrder->save(); - } - - if ($response['hateoasLinks']) { - $hateoasLinkService = new HateoasLinkService($response['hateoasLinks']); - $approveLink = $hateoasLinkService->getApproveLink(); - if ($approveLink) { - $response['approveUrl'] = $approveLink->getUrl(); - } - } - - $this->outputJson($response); + $paymentService->doPatchPayPalOrder( + Registry::getSession()->getBasket(), + $paypalOrderId + ); } public function captureGooglePayOrder(): void { $orderService = Registry::get(ServiceFactory::class)->getOrderService(); - $sessionOrderId = (string) Registry::getSession()->getVariable('sess_challenge'); - $checkoutOrderId = (string) PayPalSession::getCheckoutOrderId(); + $checkoutOrderId = $_GET['token']; - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); $request = new OrderCaptureRequest(); try { - /** @var $result ApiOrderModel */ - $result = $orderService->capturePaymentForOrder( + $orderService->capturePaymentForOrder( '', $checkoutOrderId, $request, @@ -300,38 +277,7 @@ public function captureGooglePayOrder(): void $logger = $this->getServiceFromContainer(Logger::class); $logger->log('error', $exception->getMessage(), [$exception]); - - $result = [ - 'location' => [ - 'cl=order' - ] - ]; - $this->outputJson($result); } - - try { - $order = oxNew(EshopModelOrder::class); - $order->setId($sessionOrderId); - $order->load($sessionOrderId); - - $result = [ - 'location' => [ - 'cl=order&fnc=finalizeGooglePay' - ] - ]; - //track status in session - Registry::getSession()->setVariable('SessionGooglePay', $sessionOrderId); - Registry::getSession()->setVariable('GooglePayOrderId', $checkoutOrderId); - } catch (Exception $exception) { - $logger->log( - 'debug', - $exception->getMessage(), - [$exception] - ); - $this->getServiceFromContainer(PaymentService::class)->removeTemporaryOrder(); - } - - $this->outputJson($result); } public function captureAcdcOrder(): void @@ -512,7 +458,7 @@ public function finalizeApplePay(): string 'failure during finalizeOrderAfterExternalPayment', [$exception] ); - $this->cancelpaypalsession('cannot finalize order'); + $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('cannot finalize order'); $goNext = 'payment?payerror=2'; } @@ -529,7 +475,7 @@ public function finalizepaypalsession(): string !$sessionCheckoutOrderId || ($standardRequestId !== $sessionCheckoutOrderId); if (!$vaulting && $cancelSession) { - $this->cancelpaypalsession('request to session mismatch'); + $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('request to session mismatch'); } try { @@ -562,7 +508,7 @@ public function finalizepaypalsession(): string 'PayPal Checkout error during order finalization ' . $exception->getMessage(), [$exception] ); - $this->cancelpaypalsession('cannot finalize order'); + $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('cannot finalize order'); return 'payment?payerror=2'; } @@ -589,7 +535,7 @@ public function finalizeacdc(): string 'failure during finalizeOrderAfterExternalPayment', [$exception] ); - $this->cancelpaypalsession('cannot finalize order'); + $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('cannot finalize order'); $goNext = 'payment?payerror=2'; } @@ -597,45 +543,21 @@ public function finalizeacdc(): string } public function finalizeGooglePay(): string { - $sessionOrderId = Registry::getSession()->getVariable('sess_challenge'); - $sessionGooglePayOrderId = Registry::getSession()->getVariable('GooglePayOrderId'); - + $paypalOrderId = $_GET['token']; $forceFetchDetails = (bool) Registry::getRequest()->getRequestParameter('fallbackfinalize'); - try { - $order = oxNew(EshopModelOrder::class); - $order->load($sessionOrderId); - $order->finalizeOrderAfterExternalPayment($sessionGooglePayOrderId, $forceFetchDetails); - $goNext = 'thankyou'; - } catch (Exception $exception) { - /** @var Logger $logger */ - $logger = $this->getServiceFromContainer(Logger::class); - $logger->log( - 'error', - 'failure during finalizeOrderAfterExternalPayment', - [$exception] - ); - $this->cancelpaypalsession('cannot finalize order'); - $goNext = 'payment?payerror=2'; - } - - return $goNext; - } - public function cancelpaypalsession(string $errorcode = null): string - { - //TODO: we get the PayPal order id retuned in token parameter, can be used for paranoia checks - //(string) Registry::getRequest()->getRequestParameter('token') - $requestErrorcode = (string) Registry::getRequest()->getRequestParameter('errorcode'); + $this->createGooglePayOrder(); + $this->captureGooglePayOrder(); - $this->getServiceFromContainer(PaymentService::class) - ->removeTemporaryOrder(); + $oxidOrderId = Registry::getSession()->getBasket()->getOrderId(); - $goNext = 'payment'; - if ($errorcode || $requestErrorcode) { - $goNext = 'payment?payerror=2'; - } + /** @var GooglePayPayPalService $googlePayPayPalService */ + $googlePayPayPalService = $this->getServiceFromContainer(GooglePayPayPalService::class); + $sucesss = $googlePayPayPalService->finalizeGooglePay($oxidOrderId, $paypalOrderId, $forceFetchDetails); - return $goNext; + return $sucesss ? + 'thankyou' : + $this->getServiceFromContainer(OrderPayPalService::class)->cancelPayPalSession('cannot finalize order'); } /** diff --git a/src/Controller/ProxyController.php b/src/Controller/ProxyController.php index 2892a331..755ada0b 100644 --- a/src/Controller/ProxyController.php +++ b/src/Controller/ProxyController.php @@ -19,19 +19,21 @@ use OxidEsales\Eshop\Core\Registry; use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; use OxidEsales\EshopCommunity\Internal\Framework\Module\Facade\ModuleSettingServiceInterface; -use OxidSolutionCatalysts\PayPal\Module; -use OxidSolutionCatalysts\PayPal\Service\Logger; +use OxidSolutionCatalysts\PayPal\Core\Config; use OxidSolutionCatalysts\PayPal\Core\Constants; -use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; -use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; -use OxidSolutionCatalysts\PayPal\Service\UserRepository; use OxidSolutionCatalysts\PayPal\Core\OrderRequestFactory; use OxidSolutionCatalysts\PayPal\Core\PayPalDefinitions; use OxidSolutionCatalysts\PayPal\Core\PayPalSession; use OxidSolutionCatalysts\PayPal\Core\ServiceFactory; use OxidSolutionCatalysts\PayPal\Core\Utils\PayPalAddressResponseToOxidAddress; +use OxidSolutionCatalysts\PayPal\Module; +use OxidSolutionCatalysts\PayPal\Service\Logger; use OxidSolutionCatalysts\PayPal\Service\ModuleSettings; +use OxidSolutionCatalysts\PayPal\Service\Payment as PaymentService; +use OxidSolutionCatalysts\PayPal\Service\UserRepository; +use OxidSolutionCatalysts\PayPal\Service\PayPalUrlService; use OxidSolutionCatalysts\PayPal\Traits\JsonTrait; +use OxidSolutionCatalysts\PayPal\Traits\ServiceContainer; use OxidSolutionCatalysts\PayPalApi\Model\Orders\AddressPortable; use OxidSolutionCatalysts\PayPalApi\Model\Orders\Order as PayPalApiOrder; use OxidSolutionCatalysts\PayPalApi\Model\Orders\OrderRequest; @@ -186,6 +188,9 @@ public function createGooglepayOrder() $this->outputJson(['ERROR' => 'No Article in the Basket']); } + /** @var PayPalUrlService $payPalUrlService */ + $payPalUrlService = $this->getServiceFromContainer(PayPalUrlService::class); + $response = $this->getServiceFromContainer(PaymentService::class)->doCreatePayPalOrder( $basket, OrderRequest::INTENT_CAPTURE, @@ -195,8 +200,8 @@ public function createGooglepayOrder() '', Constants::PAYPAL_PARTNER_ATTRIBUTION_ID_PPCP, - $config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession', - $config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession', + $payPalUrlService->getReturnUrl(), + $payPalUrlService->getCancelUrl(), false ); diff --git a/src/Service/GooglePay/GooglePayPayPalService.php b/src/Service/GooglePay/GooglePayPayPalService.php new file mode 100644 index 00000000..41010ffc --- /dev/null +++ b/src/Service/GooglePay/GooglePayPayPalService.php @@ -0,0 +1,33 @@ +load($oxidOrderId); + $order->finalizeOrderAfterExternalPayment($payPalOrderId, $forceFetchDetails); + return true; + } catch (Exception $exception) { + $this->logger->log( + 'error', + __CLASS__ . ': failure during finalizeOrderAfterExternalPayment', + [$exception] + ); + } + + return false; + } +} diff --git a/src/Service/HateoasLinkService.php b/src/Service/HateoasLinkService.php index 5f2a63c7..8e810d63 100644 --- a/src/Service/HateoasLinkService.php +++ b/src/Service/HateoasLinkService.php @@ -7,29 +7,23 @@ class HateoasLinkService { - private HateoasLinks $hateoasLinks; - public function __construct(array $links) + public function getSelfLink(array $links): HateoasLink { - $this->hateoasLinks = HateoasLinks::fromArray($links); + return HateoasLinks::fromArray($links)->getSelfLink(); } - public function getSelfLink(): HateoasLink + public function getApproveLink(array $links): HateoasLink { - return $this->hateoasLinks->getSelfLink(); + return HateoasLinks::fromArray($links)->getApproveLink(); } - public function getApproveLink(): HateoasLink + public function getUpdateLink(array $links): HateoasLink { - return $this->hateoasLinks->getApproveLink(); + return HateoasLinks::fromArray($links)->getUpdateLink(); } - public function getUpdateLink(): HateoasLink + public function getCaptureLink(array $links): HateoasLink { - return $this->hateoasLinks->getUpdateLink(); - } - - public function getCaptureLink(): HateoasLink - { - return $this->hateoasLinks->getCaptureLink(); + return HateoasLinks::fromArray($links)->getCaptureLink(); } } diff --git a/src/Service/OrderPayPalService.php b/src/Service/OrderPayPalService.php new file mode 100644 index 00000000..7994d4bd --- /dev/null +++ b/src/Service/OrderPayPalService.php @@ -0,0 +1,28 @@ +getRequestParameter('token') + $requestErrorcode = (string) $this->request->getRequestParameter('errorcode'); + + $this->paymentService->removeTemporaryOrder(); + + $goNext = 'payment'; + if ($errorcode || $requestErrorcode) { + $goNext = 'payment?payerror=2'; + } + + return $goNext; + } +} diff --git a/src/Service/PayPalUrlService.php b/src/Service/PayPalUrlService.php new file mode 100644 index 00000000..0428130b --- /dev/null +++ b/src/Service/PayPalUrlService.php @@ -0,0 +1,26 @@ +config->getSslShopUrl() . 'index.php?cl=order&fnc=cancelpaypalsession'; + } + public function getReturnUrl(): string + { + return $this->session->getVariable('paymentid') === PayPalDefinitions::GOOGLEPAY_PAYPAL_PAYMENT_ID ? + $this->config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizeGooglePay&stoken=' + . $this->session->getSessionChallengeToken() : + $this->config->getSslShopUrl() . 'index.php?cl=order&fnc=finalizepaypalsession'; + } +} diff --git a/views/twig/extensions/themes/default/layout/base.html.twig b/views/twig/extensions/themes/default/layout/base.html.twig index 086c79a7..8a21b3ff 100644 --- a/views/twig/extensions/themes/default/layout/base.html.twig +++ b/views/twig/extensions/themes/default/layout/base.html.twig @@ -12,7 +12,7 @@ (className == 'basket' and oViewConf.showPayPalBasketButton()) ) %} - +