Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAYSHIP-3146 - Improve the Apple Pay Setup #1300

Merged
merged 3 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<module>
<name>ps_checkout</name>
<displayName><![CDATA[PrestaShop Checkout]]></displayName>
<version><![CDATA[8.4.2.2]]></version>
<version><![CDATA[8.4.3.0]]></version>
<description><![CDATA[Provide the most commonly used payment methods to your customers in this all-in-one module, and manage all your sales in a centralized interface.]]></description>
<author><![CDATA[PrestaShop]]></author>
<tab><![CDATA[payments_gateways]]></tab>
Expand Down
11 changes: 11 additions & 0 deletions config/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -486,3 +486,14 @@ services:
public: true
arguments:
- '@PrestaShop\Module\PrestashopCheckout\Translations\Translations'

PrestaShop\Module\PrestashopCheckout\System\SystemConfiguration:
class: 'PrestaShop\Module\PrestashopCheckout\System\SystemConfiguration'
public: true

PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\AppleSetup:
class: 'PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\AppleSetup'
public: true
arguments:
- '@PrestaShop\Module\PrestashopCheckout\System\SystemConfiguration'
- '@PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration'
25 changes: 25 additions & 0 deletions controllers/admin/AdminAjaxPrestashopCheckoutController.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
use PrestaShop\Module\PrestashopCheckout\Order\State\Exception\OrderStateException;
use PrestaShop\Module\PrestashopCheckout\Order\State\OrderStateInstaller;
use PrestaShop\Module\PrestashopCheckout\Order\State\Service\OrderStateMapper;
use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\AppleSetup;
use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Exception\ApplePaySetupException;
use PrestaShop\Module\PrestashopCheckout\PayPal\Mode;
use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Command\RefundPayPalCaptureCommand;
use PrestaShop\Module\PrestashopCheckout\PayPal\Payment\Refund\Exception\PayPalRefundException;
Expand Down Expand Up @@ -1067,4 +1069,27 @@ public function ajaxProcessDownloadLogs()
readfile($file->getRealPath());
exit;
}

public function ajaxProcessSetupApplePay()
{
/** @var AppleSetup $appleSetup */
$appleSetup = $this->module->getService(AppleSetup::class);

try {
$appleSetup->setup();
} catch (ApplePaySetupException $e) {
$this->exitWithResponse([
'httpCode' => 500,
'status' => false,
'error' => [
'message' => $e->getMessage(),
'code' => $e->getCode(),
],
]);
}

$this->exitWithResponse([
'status' => true,
]);
}
}
4 changes: 2 additions & 2 deletions ps_checkout.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class Ps_checkout extends PaymentModule

// Needed in order to retrieve the module version easier (in api call headers) than instanciate
// the module each time to get the version
const VERSION = '8.4.2.2';
const VERSION = '8.4.3.0';

const INTEGRATION_DATE = '2024-04-01';

Expand All @@ -137,7 +137,7 @@ public function __construct()

// We cannot use the const VERSION because the const is not computed by addons marketplace
// when the zip is uploaded
$this->version = '8.4.2.2';
$this->version = '8.4.3.0';
$this->author = 'PrestaShop';
$this->currencies = true;
$this->currencies_mode = 'checkbox';
Expand Down
223 changes: 223 additions & 0 deletions src/PayPal/ApplePay/AppleSetup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay;

use Configuration;
use Exception;
use Hook;
use Module;
use PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Exception\ApplePaySetupException;
use PrestaShop\Module\PrestashopCheckout\PayPal\PayPalConfiguration;
use PrestaShop\Module\PrestashopCheckout\System\SystemConfiguration;
use Shop;

class AppleSetup
{
/**
* @var SystemConfiguration
*/
private $systemConfiguration;

/**
* @var PayPalConfiguration
*/
private $payPalConfiguration;

public function __construct(SystemConfiguration $systemConfiguration, PayPalConfiguration $payPalConfiguration)
{
$this->systemConfiguration = $systemConfiguration;
$this->payPalConfiguration = $payPalConfiguration;
}

/**
* @return void
*
* @throws ApplePaySetupException
*/
public function setup()
{
if ($this->systemConfiguration->isApacheServer() && !$this->checkWellKnownFileExist()) {
$this->registerModuleRoutesHook();
} else {
$this->copyWellKnownFile();
}
}

/**
* @return void
*
* @throws ApplePaySetupException
*/
public function registerModuleRoutesHook()
{
try {
$module = Module::getInstanceByName('ps_checkout');
$shopList = Shop::getCompleteListOfShopsID();
if (!Hook::registerHook($module, 'moduleRoutes', $shopList)) {
throw new ApplePaySetupException('Failed to register moduleRoutes hook for ps_checkout.', ApplePaySetupException::FAILED_REGISTER_HOOK);
}
} catch (Exception $e) {
throw new ApplePaySetupException('Failed to register moduleRoutes hook for ps_checkout.', ApplePaySetupException::ERROR_REGISTER_HOOK, $e);
}
}

/**
* @param string $wellKnownDir
*
* @return string
*/
public function getDestinationFile($wellKnownDir)
{
return $wellKnownDir . '/apple-developer-merchantid-domain-association';
}

/**
* @return bool
*
* @throws ApplePaySetupException
*/
public function checkWellKnownFileExist()
{
$rootDir = $this->getPrestaShopRootDir();
$wellKnownDir = $this->getWellKnownDir($rootDir);
$destinationFile = $this->getDestinationFile($wellKnownDir);

return file_exists($destinationFile);
}

/**
* @return void
*
* @throws ApplePaySetupException
*/
public function copyWellKnownFile()
{
$rootDir = $this->getPrestaShopRootDir();
$this->checkPrestaShopIsAtDomainRoot();
$wellKnownDir = $this->getWellKnownDir($rootDir);
$sourceFile = $this->getSourceFile();
$destinationFile = $this->getDestinationFile($wellKnownDir);

if (file_exists($destinationFile) && !$this->isWritable($destinationFile)) {
throw new ApplePaySetupException('The Apple Domain Association file is not writable in the PrestaShop root directory.', ApplePaySetupException::APPLE_DOMAIN_FILE_NOT_WRITABLE);
}

if (!copy($sourceFile, $destinationFile)) {
throw new ApplePaySetupException('Failed to copy the "apple-developer-merchantid-domain-association" file to the PrestaShop root directory.', ApplePaySetupException::FAILED_COPY_APPLE_DOMAIN_FILE);
}
}

/**
* @return string
*
* @throws ApplePaySetupException
*/
public function getPrestaShopRootDir()
{
$rootDir = defined('_PS_ROOT_DIR_') ? constant('_PS_ROOT_DIR_') : null;

if (!$rootDir || !is_dir($rootDir)) {
throw new ApplePaySetupException('Unable to retrieve the PrestaShop Root directory path.', ApplePaySetupException::UNABLE_RETRIEVE_ROOT_DIR);
}

return $rootDir;
}

/**
* @return void
*
* @throws ApplePaySetupException
*/
public function checkPrestaShopIsAtDomainRoot()
{
$defaultShop = new Shop((int) Configuration::get('PS_SHOP_DEFAULT'));

if (!$defaultShop->physical_uri) {
throw new ApplePaySetupException('Unable to retrieve the base URI of the shop.', ApplePaySetupException::UNABLE_RETRIEVE_BASE_URI);
}

if ($defaultShop->physical_uri !== '/') {
throw new ApplePaySetupException('PrestaShop is not installed at the domain root.', ApplePaySetupException::PRESTASHOP_NOT_AT_DOMAIN_ROOT);
}
}

/**
* @param string $rootDir
*
* @return string
*
* @throws ApplePaySetupException
*/
public function getWellKnownDir($rootDir)
{
$wellKnownDir = $rootDir . '/.well-known';

if (!is_dir($wellKnownDir)) {
if (!$this->createDir($wellKnownDir)) {
throw new ApplePaySetupException('Failed to create the ".well-known" directory in the PrestaShop root directory.', ApplePaySetupException::FAILED_CREATE_WELL_KNOWN_DIR);
}
}

if (!$this->isWritable($wellKnownDir)) {
throw new ApplePaySetupException('The ".well-known" directory is not writable in the PrestaShop root directory.', ApplePaySetupException::WELL_KNOWN_DIR_NOT_WRITABLE);
}

return $wellKnownDir;
}

/**
* @return string
*
* @throws ApplePaySetupException
*/
public function getSourceFile()
{
$moduleWellKnownDir = _PS_MODULE_DIR_ . 'ps_checkout/.well-known';
$paypalEnvironment = $this->payPalConfiguration->getPaymentMode();
$sourceFile = "$moduleWellKnownDir/apple-$paypalEnvironment-merchantid-domain-association";

if (!file_exists($sourceFile)) {
throw new ApplePaySetupException('The Apple Domain Association file could not be found in the module directory.', ApplePaySetupException::APPLE_DOMAIN_FILE_NOT_FOUND);
}

return $sourceFile;
}

/**
* @param string $wellKnownDir
*
* @return bool
*/
public function createDir($wellKnownDir)
{
return mkdir($wellKnownDir, 0755, true);
}

/**
* @param string $wellKnownDir
*
* @return bool
*/
public function isWritable($wellKnownDir)
{
return is_writable($wellKnownDir);
}
}
37 changes: 37 additions & 0 deletions src/PayPal/ApplePay/Exception/ApplePaySetupException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

namespace PrestaShop\Module\PrestashopCheckout\PayPal\ApplePay\Exception;

use PrestaShop\Module\PrestashopCheckout\Exception\PsCheckoutException;

class ApplePaySetupException extends PsCheckoutException
{
const FAILED_REGISTER_HOOK = 1001;
const ERROR_REGISTER_HOOK = 1002;
const UNABLE_RETRIEVE_ROOT_DIR = 2001;
const FAILED_CREATE_WELL_KNOWN_DIR = 2002;
const WELL_KNOWN_DIR_NOT_WRITABLE = 2003;
const PRESTASHOP_NOT_AT_DOMAIN_ROOT = 2004;
const UNABLE_RETRIEVE_BASE_URI = 2005;
const APPLE_DOMAIN_FILE_NOT_FOUND = 3001;
const APPLE_DOMAIN_FILE_NOT_WRITABLE = 3002;
const FAILED_COPY_APPLE_DOMAIN_FILE = 3003;
}
Loading
Loading