Merge pull request #7 from inpsyde/settings-overhaul

replace wc gateway settings with independent settings system
This commit is contained in:
David Remer 2020-07-02 13:26:31 +03:00 committed by GitHub
commit 4676a8b5dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 746 additions and 703 deletions

View file

@ -29,4 +29,4 @@ jobs:
- name: Run test suite
run: ./vendor/bin/phpunit
- name: Run cs
run: ./vendor/bin/phpcs src modules.local/ppcp-wc-gateway modules.local/ppcp-button/src/ modules.local/ppcp-onboarding/src/ --standard=Inpsyde
run: ./vendor/bin/phpcs src modules.local/ppcp-wc-gateway/src/ modules.local/ppcp-button/src/ modules.local/ppcp-onboarding/src/ --standard=Inpsyde

View file

@ -17,7 +17,7 @@ use Inpsyde\PayPalCommerce\Onboarding\Environment;
use Inpsyde\PayPalCommerce\Onboarding\State;
return [
'button.client_id' => static function(ContainerInterface $container) : string {
'button.client_id' => static function (ContainerInterface $container): string {
$settings = $container->get('wcgateway.settings');
$clientId = $settings->has('client_id') ? $settings->get('client_id') : '';
@ -32,10 +32,9 @@ return [
/**
* ToDo: Add production platform client Id.
* ToDo: We do not correctly detect sandbox mode when we use the current sandbox field switch in Settings. Bugfix needs to be fixed asap.
*/
return $env->currentEnvironmentIs(Environment::SANDBOX) ?
'AQB97CzMsd58-It1vxbcDAGvMuXNCXRD9le_XUaMlHB_U7XsU9IiItBwGQOtZv9sEeD6xs2vlIrL4NiD' : 'AQB97CzMsd58-It1vxbcDAGvMuXNCXRD9le_XUaMlHB_U7XsU9IiItBwGQOtZv9sEeD6xs2vlIrL4NiD';
'AQB97CzMsd58-It1vxbcDAGvMuXNCXRD9le_XUaMlHB_U7XsU9IiItBwGQOtZv9sEeD6xs2vlIrL4NiD' : '';
},
'button.smart-button' => static function (ContainerInterface $container): SmartButtonInterface {
@ -47,7 +46,7 @@ return [
return new DisabledSmartButton();
}
$settings = $container->get('wcgateway.settings');
if (!$settings->has('enabled') || ! wc_string_to_bool($settings->get('enabled'))) {
if (!$settings->has('enabled') || ! $settings->get('enabled')) {
return new DisabledSmartButton();
}
$payeeRepository = $container->get('api.repository.payee');
@ -64,7 +63,6 @@ return [
$payerFactory,
$clientId
);
},
'button.url' => static function (ContainerInterface $container): string {
return plugins_url(

View file

@ -43,6 +43,11 @@ class SmartButton implements SmartButtonInterface
$this->clientId = $clientId;
}
// phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
/**
* ToDo: Refactor
* @return bool
*/
public function renderWrapper(): bool
{
@ -77,7 +82,7 @@ class SmartButton implements SmartButtonInterface
};
$notEnabledOnCart = $this->settings->has('button_cart_enabled') &&
!wc_string_to_bool($this->settings->get('button_cart_enabled'));
!$this->settings->get('button_cart_enabled');
if (
is_cart()
&& !$notEnabledOnCart
@ -91,7 +96,7 @@ class SmartButton implements SmartButtonInterface
if (
is_cart()
&& $this->settings->has('dcc_cart_enabled')
&& wc_string_to_bool($this->settings->get('dcc_cart_enabled'))
&& $this->settings->get('dcc_cart_enabled')
) {
add_action(
'woocommerce_proceed_to_checkout',
@ -101,7 +106,7 @@ class SmartButton implements SmartButtonInterface
}
$notEnabledOnProductPage = $this->settings->has('button_single_product_enabled') &&
!wc_string_to_bool($this->settings->get('button_single_product_enabled'));
!$this->settings->get('button_single_product_enabled');
if (
is_product()
&& !$notEnabledOnProductPage
@ -115,7 +120,7 @@ class SmartButton implements SmartButtonInterface
if (
is_product()
&& $this->settings->has('dcc_single_product_enabled')
&& wc_string_to_bool($this->settings->get('dcc_single_product_enabled'))
&& $this->settings->get('dcc_single_product_enabled')
) {
add_action(
'woocommerce_single_product_summary',
@ -124,7 +129,7 @@ class SmartButton implements SmartButtonInterface
);
}
$notEnabledOnMiniCart = $this->settings->has('button_mini_cart_enabled') &&
!wc_string_to_bool($this->settings->get('button_mini_cart_enabled'));
!$this->settings->get('button_mini_cart_enabled');
if (
! $notEnabledOnMiniCart
) {
@ -138,7 +143,7 @@ class SmartButton implements SmartButtonInterface
}
if (
$this->settings->has('dcc_mini_cart_enabled')
&& wc_string_to_bool($this->settings->get('dcc_mini_cart_enabled'))
&& $this->settings->get('dcc_mini_cart_enabled')
) {
add_action(
'woocommerce_widget_shopping_cart_after_buttons',
@ -155,7 +160,7 @@ class SmartButton implements SmartButtonInterface
);
if (
$this->settings->has('dcc_checkout_enabled')
&& wc_string_to_bool($this->settings->get('dcc_checkout_enabled'))
&& $this->settings->get('dcc_checkout_enabled')
) {
add_action(
'woocommerce_review_order_after_submit',
@ -165,6 +170,7 @@ class SmartButton implements SmartButtonInterface
}
return true;
}
// phpcs:enable Inpsyde.CodeQuality.FunctionLength.TooLong
public function enqueue(): bool
{
@ -316,7 +322,7 @@ class SmartButton implements SmartButtonInterface
'dcc_single_product_enabled',
];
foreach ($keys as $key) {
if ($this->settings->has($key) && wc_string_to_bool($this->settings->get($key))) {
if ($this->settings->has($key) && $this->settings->get($key)) {
return true;
}
}

View file

@ -0,0 +1,13 @@
function onboardingCallback(authCode, sharedId) {
fetch(PayPalCommerceGatewayOnboarding.endpoint, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
authCode: authCode,
sharedId: sharedId,
nonce: PayPalCommerceGatewayOnboarding.nonce
})
});
}

View file

@ -115,12 +115,12 @@ return [
$requestData = $container->get('button.request-data');
$loginSellerEndpoint = $container->get('api.endpoint.login-seller');
$partnerReferralsData = $container->get('api.repository.partner-referrals-data');
$gateway = $container->get('wcgateway.gateway.base');
$settings = $container->get('wcgateway.settings');
return new LoginSellerEndpoint(
$requestData,
$loginSellerEndpoint,
$partnerReferralsData,
$gateway
$settings
);
},
'onboarding.render' => static function (ContainerInterface $container) : OnboardingRenderer {

View file

@ -1,9 +1,9 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Onboarding\Assets;
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
use Inpsyde\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
use Inpsyde\PayPalCommerce\Onboarding\State;
@ -19,12 +19,13 @@ class OnboardingAssets
State $state,
LoginSellerEndpoint $loginSellerEndpoint
) {
$this->moduleUrl = $moduleUrl;
$this->state = $state;
$this->loginSellerEndpoint = $loginSellerEndpoint;
}
public function register() : bool
public function register(): bool
{
if (!$this->shouldRender()) {
@ -51,8 +52,8 @@ class OnboardingAssets
return true;
}
public function enqueue() : bool {
public function enqueue(): bool
{
if (! $this->shouldRender()) {
return false;
}
@ -61,7 +62,9 @@ class OnboardingAssets
return true;
}
private function shouldRender() : bool {
private function shouldRender(): bool
{
// phpcs:disable Inpsyde.CodeQuality.VariablesName.SnakeCaseVar
global $current_section;
if ($current_section !== 'ppcp-gateway') {
return false;
@ -70,4 +73,4 @@ class OnboardingAssets
$shouldRender = $this->state->currentState() === State::STATE_PROGRESSIVE;
return $shouldRender;
}
}
}

View file

@ -1,14 +1,15 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Onboarding\Endpoint;
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
use Inpsyde\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
use Inpsyde\PayPalCommerce\Button\Endpoint\EndpointInterface;
use Inpsyde\PayPalCommerce\Button\Endpoint\RequestData;
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGatewayInterface;
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
class LoginSellerEndpoint implements EndpointInterface
{
@ -17,17 +18,18 @@ class LoginSellerEndpoint implements EndpointInterface
private $requestData;
private $loginSellerEndpoint;
private $partnerReferralsData;
private $gateway;
private $settings;
public function __construct(
RequestData $requestData,
LoginSeller $loginSellerEndpoint,
PartnerReferralsData $partnerReferralsData,
\WC_Payment_Gateway $gateway
Settings $settings
) {
$this->requestData = $requestData;
$this->loginSellerEndpoint = $loginSellerEndpoint;
$this->partnerReferralsData = $partnerReferralsData;
$this->gateway = $gateway;
$this->settings = $settings;
}
public static function nonce(): string
@ -45,8 +47,9 @@ class LoginSellerEndpoint implements EndpointInterface
$data['authCode'],
$this->partnerReferralsData->nonce()
);
$this->gateway->update_option('client_secret', $credentials->client_secret);
$this->gateway->update_option('client_id', $credentials->client_id);
$this->settings->set('client_secret', $credentials->client_secret);
$this->settings->set('client_id', $credentials->client_id);
$this->settings->persist();
wp_send_json_success();
return true;
} catch (\RuntimeException $error) {

View file

@ -1,9 +1,9 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Onboarding;
use Psr\Container\ContainerInterface;
class Environment
@ -11,12 +11,6 @@ class Environment
public const PRODUCTION = 'production';
public const SANDBOX = 'sandbox';
public const VALID_ENVIRONMENTS = [
self::PRODUCTION,
self::SANDBOX,
];
public const OPTION_KEY = 'ppcp-env';
private $settings;
public function __construct(ContainerInterface $settings)
@ -24,23 +18,15 @@ class Environment
$this->settings = $settings;
}
public function currentEnvironment() : string
public function currentEnvironment(): string
{
return (
$this->settings->has('sandbox_on') && wc_string_to_bool($this->settings->get('sandbox_on'))
$this->settings->has('sandbox_on') && $this->settings->get('sandbox_on')
) ? self::SANDBOX : self::PRODUCTION;
}
public function currentEnvironmentIs(string $environment) : bool {
public function currentEnvironmentIs(string $environment): bool
{
return $this->currentEnvironment() === $environment;
}
public function changeEnvironmentTo(string $environment) : bool
{
if (! in_array($environment, self::VALID_ENVIRONMENTS, true)) {
return false;
}
update_option(self::OPTION_KEY, $environment);
return true;
}
}
}

View file

@ -8,6 +8,7 @@ use Dhii\Container\ServiceProvider;
use Dhii\Modular\Module\ModuleInterface;
use Inpsyde\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
use Inpsyde\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
use Inpsyde\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
use Interop\Container\ServiceProviderInterface;
use Psr\Container\ContainerInterface;
@ -43,6 +44,25 @@ class OnboardingModule implements ModuleInterface
]
);
add_filter(
'woocommerce_form_field',
static function ($field, $key, $config) use ($container) {
if ($config['type'] !== 'ppcp_onboarding') {
return $field;
}
$renderer = $container->get('onboarding.render');
/**
* @var OnboardingRenderer $renderer
*/
ob_start();
$renderer->render();
$content = ob_get_contents();
ob_end_clean();
return $content;
},
10,
3
);
add_action(
'wc_ajax_' . LoginSellerEndpoint::ENDPOINT,

View file

@ -1,9 +1,9 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Onboarding\Render;
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\PartnerReferrals;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
@ -16,7 +16,8 @@ class OnboardingRenderer
$this->partnerReferrals = $partnerReferrals;
}
public function render() {
public function render()
{
try {
$url = add_query_arg(
[
@ -25,26 +26,6 @@ class OnboardingRenderer
$this->partnerReferrals->signupLink()
);
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo esc_html_e('Connect to PayPal', 'woocommerce-paypal-commerce-gateway'); ?>
</th>
<td class="forminp">
<script>
function onboardingCallback(authCode, sharedId) {
fetch(PayPalCommerceGatewayOnboarding.endpoint, {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
authCode: authCode,
sharedId: sharedId,
nonce: PayPalCommerceGatewayOnboarding.nonce
})
});
}
</script>
<a
target="_blank"
class="button-primary"
@ -52,29 +33,21 @@ class OnboardingRenderer
href="<?php echo esc_url($url); ?>"
data-paypal-button="true"
><?php
esc_html_e('Sign up for PayPal', 'woocommerce-paypal-commerce-gateway');
esc_html_e(
'Sign up for PayPal',
'woocommerce-paypal-commerce-gateway'
);
?></a>
<script
id="paypal-js"
src="https://www.sandbox.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js"
></script>
</td>
</tr>
<?php
} catch(RuntimeException $exception) {
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo esc_html_e('Connect to PayPal', 'woocommerce-paypal-commerce-gateway'); ?>
</th>
<td>
<?php echo esc_html_e(
'We could not properly connect to PayPal. Please reload the page to continue',
'woocommerce-paypal-commerce-gateway'
); ?>
</td>
</tr>
<?php
} catch (RuntimeException $exception) {
esc_html_e(
'We could not properly connect to PayPal. Please reload the page to continue',
'woocommerce-paypal-commerce-gateway'
);
}
}
}
}

View file

@ -1,16 +1,16 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Onboarding;
use Psr\Container\ContainerInterface;
class State
{
const STATE_START = 0;
const STATE_PROGRESSIVE = 4;
const STATE_ONBOARDED = 8;
public const STATE_START = 0;
public const STATE_PROGRESSIVE = 4;
public const STATE_ONBOARDED = 8;
private $environment;
private $settings;
@ -18,11 +18,13 @@ class State
Environment $environment,
ContainerInterface $settings
) {
$this->environment = $environment;
$this->settings = $settings;
}
public function currentState() : int {
public function currentState(): int
{
$value = self::STATE_START;
/**
* Having provided the merchant email means, we are at least
@ -35,9 +37,9 @@ class State
/**
* Once we can fetch credentials we are completely onboarded.
*/
if ($this->settings->has('client_id')) {
if ($this->settings->has('client_id') && $this->settings->get('client_id')) {
$value = self::STATE_ONBOARDED;
}
return $value;
}
}
}

View file

@ -4,26 +4,28 @@ declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway;
use Psr\Container\ContainerInterface;
return [
'api.merchant_email' => function ($container) : string {
'api.merchant_email' => static function (ContainerInterface $container): string {
$settings = $container->get('wcgateway.settings');
return $settings->has('merchant_email') ? (string) $settings->get('merchant_email') : '';
},
'api.merchant_id' => function ($container) : string {
'api.merchant_id' => static function (ContainerInterface $container): string {
$settings = $container->get('wcgateway.settings');
return $settings->has('merchant_id') ? (string) $settings->get('merchant_id') : '';
},
'api.partner_merchant_id' => static function () : string {
'api.partner_merchant_id' => static function (): string {
// ToDo: Replace with the real merchant id of platform
return 'KQ8FCM66JFGDL';
},
'api.key' => function ($container) : string {
'api.key' => static function (ContainerInterface $container): string {
$settings = $container->get('wcgateway.settings');
$key = $settings->has('client_id') ? (string) $settings->get('client_id') : '';
return $key;
},
'api.secret' => function ($container) : string {
'api.secret' => static function (ContainerInterface $container): string {
$settings = $container->get('wcgateway.settings');
return $settings->has('client_secret') ? (string) $settings->get('client_secret') : '';
},

View file

@ -20,32 +20,27 @@ use Inpsyde\PayPalCommerce\WcGateway\Settings\FullyOnboardedSettings;
use Inpsyde\PayPalCommerce\WcGateway\Settings\ProgressiveSettings;
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsFields;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsListener;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use Inpsyde\PayPalCommerce\WcGateway\Settings\StartSettings;
return [
'wcgateway.gateway.base' => static function (ContainerInterface $container): WcGatewayBase {
return new WcGatewayBase();
},
'wcgateway.gateway.reset' => static function (ContainerInterface $container): ResetGateway {
return new ResetGateway(
$container->get('wcgateway.settings')
);
},
'wcgateway.gateway' => static function (ContainerInterface $container): WcGateway {
$orderProcessor = $container->get('wcgateway.order-processor');
$settingsFields = $container->get('wcgateway.settings.fields');
$settingsRenderer = $container->get('wcgateway.settings.render');
$authorizedPayments = $container->get('wcgateway.processor.authorized-payments');
$notice = $container->get('wcgateway.notice.authorize-order-action');
$onboardingRender = $container->get('onboarding.render');
$reset = $container->get('wcgateway.gateway.reset');
return new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPayments,
$notice,
$onboardingRender,
$reset
$onboardingRender
);
},
'wcgateway.disabler' => static function (ContainerInterface $container): DisableGateways {
@ -65,19 +60,16 @@ return [
static function (ContainerInterface $container): AuthorizeOrderActionNotice {
return new AuthorizeOrderActionNotice();
},
'wcgateway.settings.fields' => static function (ContainerInterface $container): SettingsFields {
'wcgateway.settings.render' => static function (ContainerInterface $container): SettingsRenderer {
$settings = $container->get('wcgateway.settings');
$state = $container->get('onboarding.state');
/**
* @var State $state
*/
if ($state->currentState() === State::STATE_START) {
return new StartSettings();
}
$environment = $container->get('onboarding.environment');
if ($state->currentState() === State::STATE_PROGRESSIVE) {
return new ProgressiveSettings($environment);
}
return new FullyOnboardedSettings($environment);
$fields = $container->get('wcgateway.settings.fields');
return new SettingsRenderer($settings, $state, $fields);
},
'wcgateway.settings.listener' => static function (ContainerInterface $container): SettingsListener {
$settings = $container->get('wcgateway.settings');
$fields = $container->get('wcgateway.settings.fields');
return new SettingsListener($settings, $fields);
},
'wcgateway.order-processor' => static function (ContainerInterface $container): OrderProcessor {
@ -106,4 +98,267 @@ return [
$settings = $container->get('wcgateway.settings');
return new OrderTablePaymentStatusColumn($settings);
},
'wcgateway.settings.fields' => static function (ContainerInterface $container): array {
$settings = $container->get('wcgateway.settings');
$sandboxText = $settings->has('sandbox_on') && $settings->get('sandbox_on') ?
__(
'You are currently in the sandbox mode to test your installation. You can switch this, by clicking <button name="%1$s" value="%2$s">Reset</button>',
'woocommerce-paypal-commerce-gateway'
) : __(
'You are in live mode. This means, you can receive money into your account. You can switch this, by clicking <button name="%1$s" value="%2$s">Reset</button>',
'woocommerce-paypal-commerce-gateway'
);
$sandboxText = sprintf(
$sandboxText,
'save',
'reset'
);
$merchantEmailText = sprintf(
__(
'You are connected with your email address <mark>%1$s</mark>.
If you want to change this settings, please click <button name="%2$s" value="%3$s">Reset</button>',
'woocommerce-paypal-commerce-gateway'
),
$settings->has('merchant_email') ? $settings->get('merchant_email') : '',
'save',
'reset'
);
return [
'ppcp_onboarding' => [
'title' => __('Connect to PayPal', 'woocommerce-paypal-gateway'),
'type' => 'ppcp_onboarding',
'screens' => [
State::STATE_PROGRESSIVE,
],
],
'sandbox_on' => [
'title' => __('Sandbox', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('To test your Woocommerce installation, you can use the sandbox mode.', 'woocommerce-paypal-gateway'),
'default' => 0,
'screens' => [
State::STATE_START,
],
],
'sandbox_on_info' => [
'title' => __('Sandbox', 'woocommerce-paypal-gateway'),
'type' => 'ppcp-text',
'text' => $sandboxText,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
'hidden' => 'sandbox_on',
],
'merchant_email' => [
'title' => __('Email address', 'woocommerce-paypal-gateway'),
'type' => 'text',
'label' => __('The email address of your PayPal account.', 'woocommerce-paypal-gateway'),
'default' => '',
'screens' => [
State::STATE_START,
],
],
'merchant_email_info' => [
'title' => __('Email address', 'woocommerce-paypal-gateway'),
'type' => 'ppcp-text',
'text' => $merchantEmailText,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
'hidden' => 'merchant_email',
],
'title' => [
'title' => __('Title', 'woocommerce-paypal-gateway'),
'type' => 'text',
'description' => __(
'This controls the title which the user sees during checkout.',
'woocommerce-paypal-gateway'
),
'default' => __('PayPal', 'woocommerce-paypal-gateway'),
'desc_tip' => true,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'description' => [
'title' => __('Description', 'woocommerce-paypal-gateway'),
'type' => 'text',
'desc_tip' => true,
'description' => __(
'This controls the description which the user sees during checkout.',
'woocommerce-paypal-gateway'
),
'default' => __(
'Pay via PayPal; you can pay with your credit card if you don\'t have a PayPal account.',
'woocommerce-paypal-gateway'
),
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'button_single_product_enabled' => [
'title' => __('Buttons on Single Product', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Single Product', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'button_mini_cart_enabled' => [
'title' => __('Buttons on Mini Cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Mini Cart', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'button_cart_enabled' => [
'title' => __('Buttons on Cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Cart', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'button_color' => [
'title' => __('Color', 'woocommerce-paypal-gateway'),
'type' => 'select',
'class' => ['wc-enhanced-select'],
'default' => 'gold',
'desc_tip' => true,
'description' => __(
'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
'woocommerce-paypal-gateway'
),
'options' => [
'gold' => __('Gold (Recommended)', 'woocommerce-paypal-gateway'),
'blue' => __('Blue', 'woocommerce-paypal-gateway'),
'silver' => __('Silver', 'woocommerce-paypal-gateway'),
'black' => __('Black', 'woocommerce-paypal-gateway'),
],
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'button_shape' => [
'title' => __('Shape', 'woocommerce-paypal-gateway'),
'type' => 'select',
'class' => ['wc-enhanced-select'],
'default' => 'rect',
'desc_tip' => true,
'description' => __(
'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
'woocommerce-paypal-gateway'
),
'options' => [
'pill' => __('Pill', 'woocommerce-paypal-gateway'),
'rect' => __('Rectangle', 'woocommerce-paypal-gateway'),
],
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'disable_funding' => [
'title' => __('Disable funding sources', 'woocommerce-paypal-gateway'),
'type' => 'ppcp-multiselect',
'class' => ['wc-enhanced-select'],
'default' => [],
'desc_tip' => true,
'description' => __(
'By default all possible funding sources will be shown. You can disable some sources, if you wish.',
'woocommerce-paypal-gateway'
),
'options' => [
'card' => _x('Credit or debit cards', 'Name of payment method', 'woocommerce-paypal-gateway'),
'credit' => _x('PayPal Credit', 'Name of payment method', 'woocommerce-paypal-gateway'),
'venmo' => _x('Venmo', 'Name of payment method', 'woocommerce-paypal-gateway'),
'sepa' => _x('SEPA-Lastschrift', 'Name of payment method', 'woocommerce-paypal-gateway'),
'bancontact' => _x('Bancontact', 'Name of payment method', 'woocommerce-paypal-gateway'),
'eps' => _x('eps', 'Name of payment method', 'woocommerce-paypal-gateway'),
'giropay' => _x('giropay', 'Name of payment method', 'woocommerce-paypal-gateway'),
'ideal' => _x('iDEAL', 'Name of payment method', 'woocommerce-paypal-gateway'),
'mybank' => _x('MyBank', 'Name of payment method', 'woocommerce-paypal-gateway'),
'p24' => _x('Przelewy24', 'Name of payment method', 'woocommerce-paypal-gateway'),
'sofort' => _x('Sofort', 'Name of payment method', 'woocommerce-paypal-gateway'),
],
'screens' => [
State::STATE_PROGRESSIVE,
State::STATE_ONBOARDED,
],
],
'dcc_cart_enabled' => [
'title' => __('Enable credit card on cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card directly in your cart.', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_ONBOARDED,
],
],
'dcc_mini_cart_enabled' => [
'title' => __('Enable credit card on mini cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card directly in your mini cart.', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_ONBOARDED,
],
],
'dcc_checkout_enabled' => [
'title' => __('Enable credit card on checkout', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card in the checkout.', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_ONBOARDED,
],
],
'dcc_single_product_enabled' => [
'title' => __('Enable credit card on products', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card instantly on the product page.', 'woocommerce-paypal-gateway'),
'default' => 1,
'screens' => [
State::STATE_ONBOARDED,
],
],
'disable_cards' => [
'title' => __('Disable specific credid cards', 'woocommerce-paypal-gateway'),
'type' => 'ppcp-multiselect',
'class' => ['wc-enhanced-select'],
'default' => [],
'desc_tip' => true,
'description' => __(
'By default all possible credit cards will be shown. You can disable some cards, if you wish.',
'woocommerce-paypal-gateway'
),
'options' => [
'visa' => _x('Visa', 'Name of credit card', 'woocommerce-paypal-gateway'),
'mastercard' => _x('Mastercard', 'Name of credit card', 'woocommerce-paypal-gateway'),
'amex' => _x('American Express', 'Name of credit card', 'woocommerce-paypal-gateway'),
'discover' => _x('Discover', 'Name of credit card', 'woocommerce-paypal-gateway'),
'jcb' => _x('JCB', 'Name of credit card', 'woocommerce-paypal-gateway'),
'elo' => _x('Elo', 'Name of credit card', 'woocommerce-paypal-gateway'),
'hiper' => _x('Hiper', 'Name of credit card', 'woocommerce-paypal-gateway'),
],
'screens' => [
State::STATE_ONBOARDED,
],
],
];
},
];

View file

@ -1,92 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Gateway;
use Inpsyde\PayPalCommerce\AdminNotices\Entity\Message;
use Inpsyde\PayPalCommerce\AdminNotices\Repository\Repository;
use Inpsyde\PayPalCommerce\WcGateway\Settings\Settings;
class ResetGateway
{
private const NONCE = 'ppcp-reset';
private $settings;
public function __construct(Settings $settings)
{
$this->settings = $settings;
}
public function listen() : bool {
if (isset($_GET['ppcp-reset'])) {
return $this->reset();
}
if (isset($_GET['ppcp-resetted'])) {
return $this->resetted();
}
return false;
}
private function resetted() : bool {
add_filter(
Repository::NOTICES_FILTER,
function(array $notices) : array {
$notices[] = new Message(
__('Your PayPal settings have been resetted.', 'woocommerce-paypal-commerce-gateway'),
'success'
);
return $notices;
}
);
return true;
}
private function reset() : bool {
if (
! isset($_GET['nonce'] )
|| ! wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['nonce'])), self::NONCE)
|| ! current_user_can('manage_options')
) {
return false;
}
$this->settings->reset();
$url = remove_query_arg([
'nonce',
'ppcp-reset',
]);
$url = add_query_arg([
'ppcp-resetted' => 1,
],
$url
);
wp_redirect($url, 302);
exit;
}
public function render() {
$url = add_query_arg([
'ppcp-reset' => 1,
'nonce' => wp_create_nonce(self::NONCE),
]);
?>
<tr valign="top">
<th scope="row" class="titledesc">
</th>
<td class="forminp">
<a
class="button"
href="<?php echo esc_url($url); ?>"
><?php
esc_html_e('Reset', 'woocommerce-paypal-commerce-gateway');
?></a>
</td>
</tr>
<?php
}
}

View file

@ -16,6 +16,7 @@ use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsFields;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
//phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
@ -26,28 +27,25 @@ class WcGateway extends WcGatewayBase
public const INTENT_META_KEY = '_ppcp_paypal_intent';
public const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
private $settingsFields;
private $settingsRenderer;
private $authorizedPayments;
private $notice;
private $orderProcessor;
private $onboardingRenderer;
private $resetGateway;
public function __construct(
SettingsFields $settingsFields,
SettingsRenderer $settingsRenderer,
OrderProcessor $orderProcessor,
AuthorizedPaymentsProcessor $authorizedPayments,
AuthorizeOrderActionNotice $notice,
OnboardingRenderer $onboardingRenderer,
ResetGateway $resetGateway
OnboardingRenderer $onboardingRenderer
) {
$this->orderProcessor = $orderProcessor;
$this->authorizedPayments = $authorizedPayments;
$this->notice = $notice;
$this->settingsFields = $settingsFields;
$this->settingsRenderer = $settingsRenderer;
$this->onboardingRenderer = $onboardingRenderer;
$this->resetGateway = $resetGateway;
$this->method_title = __('PayPal Payments', 'woocommerce-paypal-gateway');
$this->method_description = __(
@ -74,7 +72,17 @@ class WcGateway extends WcGatewayBase
public function init_form_fields()
{
$this->form_fields = $this->settingsFields->fields();
$this->form_fields = [
'enabled' => [
'title' => __('Enable/Disable', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable PayPal Payments', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'ppcp' => [
'type' => 'ppcp',
],
];
}
public function process_payment($orderId): ?array
@ -136,44 +144,17 @@ class WcGateway extends WcGatewayBase
AuthorizedPaymentsProcessor::INACCESSIBLE => AuthorizeOrderActionNotice::NO_INFO,
AuthorizedPaymentsProcessor::NOT_FOUND => AuthorizeOrderActionNotice::NOT_FOUND,
];
$displayMessage = (isset($messageMapping[$status])) ? $messageMapping[$status] : AuthorizeOrderActionNotice::FAILED;
$displayMessage = (isset($messageMapping[$status])) ?
$messageMapping[$status]
: AuthorizeOrderActionNotice::FAILED;
$this->notice->displayMessage($displayMessage);
}
public function generate_ppcp_onboarding_html() : string
public function generate_ppcp_html(): string
{
ob_start();
$this->onboardingRenderer->render();
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function generate_ppcp_reset_html() : string
{
ob_start();
$this->resetGateway->render();
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function generate_ppcp_info_html($type, $data) : string
{
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<?php echo wp_kses_post( $data['title'] ); ?>
</th>
<td class="forminp">
<?php echo wp_kses_post( $data['text'] ); ?>
</td>
</tr>
<?php
$this->settingsRenderer->render();
$content = ob_get_contents();
ob_end_clean();
return $content;

View file

@ -8,7 +8,7 @@ use WC_Payment_Gateway;
class WcGatewayBase extends WC_Payment_Gateway implements WcGatewayInterface
{
const ID = 'ppcp-gateway';
public const ID = 'ppcp-gateway';
public function __construct()
{

View file

@ -38,7 +38,7 @@ class OrderProcessor
$this->orderFactory = $orderFactory;
}
public function process(\WC_Order $wcOrder, $woocommerce): bool
public function process(\WC_Order $wcOrder, \WooCommerce $woocommerce): bool
{
$order = $this->sessionHandler->order();
$wcOrder->update_meta_data(WcGateway::ORDER_ID_META_KEY, $order->id());
@ -50,7 +50,7 @@ class OrderProcessor
}
if ($errorMessage) {
$this->lastError = sprintf(
// translators %s is the message of the error.
// translators: %s is the message of the error.
__('Payment error: %s', 'woocommerce-paypal-gateway'),
$errorMessage
);

View file

@ -1,111 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
use Inpsyde\PayPalCommerce\Onboarding\Environment;
class FullyOnboardedSettings extends StartSettings implements SettingsFields
{
use SettingsTrait;
public function __construct(Environment $environment)
{
$this->environment = $environment;
}
public function fields(): array
{
return array_merge(
$this->gateway(),
$this->buttons(),
$this->creditCards()
);
}
private function gateway(): array
{
return array_merge(
$this->defaultFields(),
[
'intent' => [
'title' => __('Intent', 'woocommerce-paypal-gateway'),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'capture',
'desc_tip' => true,
'description' => __(
'The intent to either capture payment immediately or authorize a payment for an order after order creation.',
'woocommerce-paypal-gateway'
),
'options' => [
'capture' => __('Capture', 'woocommerce-paypal-gateway'),
'authorize' => __('Authorize', 'woocommerce-paypal-gateway'),
],
],
]
);
}
private function creditCards(): array
{
return [
'credit_card_settings' => [
'title' => __('Credit Card Settings', 'woocommerce-paypal-gateway'),
'type' => 'title',
'description' => __(
'Customize the appearance of Credit Card Payments on your site.',
'woocommerce-paypal-gateway'
),
],
'dcc_cart_enabled' => [
'title' => __('Enable credit card on cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card directly in your cart.', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'dcc_mini_cart_enabled' => [
'title' => __('Enable credit card on mini cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card directly in your mini cart.', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'dcc_checkout_enabled' => [
'title' => __('Enable credit card on checkout', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card in the checkout.', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'dcc_single_product_enabled' => [
'title' => __('Enable credit card on products', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Allow your customers to pay with credit card instantly on the product page.', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'disable_cards' => [
'title' => __('Disable specific credid cards', 'woocommerce-paypal-gateway'),
'type' => 'multiselect',
'class' => 'wc-enhanced-select',
'default' => [],
'desc_tip' => true,
'description' => __(
'By default all possible credit cards will be shown. You can disable some cards, if you wish.',
'woocommerce-paypal-gateway'
),
'options' => [
'visa' => _x('Visa', 'Name of credit card', 'woocommerce-paypal-gateway'),
'mastercard' => _x('Mastercard', 'Name of credit card', 'woocommerce-paypal-gateway'),
'amex' => _x('American Express', 'Name of credit card', 'woocommerce-paypal-gateway'),
'discover' => _x('Discover', 'Name of credit card', 'woocommerce-paypal-gateway'),
'jcb' => _x('JCB', 'Name of credit card', 'woocommerce-paypal-gateway'),
'elo' => _x('Elo', 'Name of credit card', 'woocommerce-paypal-gateway'),
'hiper' => _x('Hiper', 'Name of credit card', 'woocommerce-paypal-gateway'),
],
],
];
}
}

View file

@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
use Inpsyde\PayPalCommerce\Onboarding\Environment;
class ProgressiveSettings implements SettingsFields
{
use SettingsTrait;
public function __construct(Environment $environment)
{
$this->environment = $environment;
}
public function fields(): array
{
$fields = array_merge(
[
'onboarding' => [
'type' => 'ppcp_onboarding',
],
],
$this->defaultFields(),
[
'reset' => [
'type' => 'ppcp_reset',
],
]
);
return $fields;
}
}

View file

@ -10,11 +10,11 @@ use Psr\Container\ContainerInterface;
class Settings implements ContainerInterface
{
private $gateway;
public const KEY = 'woocommerce-ppcp-settings';
private $settings = [];
public function __construct(\WC_Payment_Gateway $gateway)
public function __construct()
{
$this->gateway = $gateway;
}
// phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration.NoReturnType
@ -24,18 +24,30 @@ class Settings implements ContainerInterface
if (!$this->has($id)) {
throw new NotFoundException();
}
return $this->gateway->get_option($id);
return $this->settings[$id];
}
public function has($id)
{
return !!$this->gateway->get_option($id);
$this->load();
return array_key_exists($id, $this->settings);
}
public function reset() : bool
public function set($id, $value)
{
$this->load();
$this->settings[$id] = $value;
}
public function persist()
{
update_option(self::KEY, $this->settings);
}
public function reset(): bool
{
$this->load();
$fieldsToReset = [
'enabled',
'intent',
@ -43,11 +55,20 @@ class Settings implements ContainerInterface
'client_secret',
'merchant_email',
];
foreach ($fieldsToReset as $key) {
$this->gateway->update_option($key, '');
foreach ($fieldsToReset as $id) {
$this->settings[$id] = null;
}
return true;
}
private function load(): bool
{
if ($this->settings) {
return false;
}
$this->settings = get_option(self::KEY, []);
return true;
}
}

View file

@ -1,13 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
//phpcs:disable Inpsyde.CodeQuality.FunctionLength.TooLong
interface SettingsFields
{
public function fields(): array;
}

View file

@ -0,0 +1,116 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
use Inpsyde\PayPalCommerce\Onboarding\State;
class SettingsListener
{
public const NONCE = 'ppcp-settings';
private $settings;
private $settingFields;
public function __construct(Settings $settings, array $settingFields)
{
$this->settings = $settings;
$this->settingFields = $settingFields;
}
public function listen()
{
if (! $this->isValidUpdateRequest()) {
return;
}
/**
* Nonce verification is done in self::isValidUpdateRequest
*/
//phpcs:disable WordPress.Security.NonceVerification.Missing
if (isset($_POST['save']) && sanitize_text_field(wp_unslash($_POST['save'])) === 'reset') {
$this->settings->reset();
$this->settings->persist();
return;
}
$settings = [
'enabled' => isset($_POST['woocommerce_ppcp-gateway_enabled'])
&& absint($_POST['woocommerce_ppcp-gateway_enabled']) === 1,
];
//phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
/**
* Sanitization is done at a later stage.
*/
$rawData = (isset($_POST['ppcp'])) ? (array) wp_unslash($_POST['ppcp']) : [];
$settings = $this->retrieveSettingsFromRawData($rawData);
foreach ($settings as $id => $value) {
$this->settings->set($id, $value);
}
$this->settings->persist();
}
//phpcs:disable Inpsyde.CodeQuality.NestingLevel.MaxExceeded
private function retrieveSettingsFromRawData(array $rawData): array
{
$settings = [];
foreach ($this->settingFields as $key => $config) {
switch ($config['type']) {
case 'checkbox':
$settings[$key] = isset($rawData[$key]);
break;
case 'text':
$settings[$key] = isset($rawData[$key]) ? sanitize_text_field($rawData[$key]) : '';
break;
case 'multiselect':
$values = isset($rawData[$key]) ? (array) $rawData[$key] : [];
$valuesToSave = [];
foreach ($values as $index => $rawValue) {
$value = sanitize_text_field($rawValue);
if (! in_array($value, $config['options'], true)) {
continue;
}
$valuesToSave[] = $value;
}
$settings[$key] = $valuesToSave;
break;
case 'select':
$settings[$key] = isset($rawData[$key]) && in_array(
sanitize_text_field($rawData[$key]),
$config['options'],
true
) ? sanitize_text_field($rawData[$key]) : null;
break;
}
}
return $settings;
}
//phpcs:enable Inpsyde.CodeQuality.NestingLevel.MaxExceeded
private function isValidUpdateRequest(): bool
{
if (
! isset($_REQUEST['section'])
|| sanitize_text_field(wp_unslash($_REQUEST['section'])) !== 'ppcp-gateway'
) {
return false;
}
if (! current_user_can('manage_options')) {
return false;
}
if (
! isset($_POST['ppcp-nonce'])
|| !wp_verify_nonce(
sanitize_text_field(wp_unslash($_POST['ppcp-nonce'])),
self::NONCE
)
) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,108 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
use Inpsyde\PayPalCommerce\Onboarding\State;
use Psr\Container\ContainerInterface;
class SettingsRenderer
{
private $settings;
private $state;
private $fields;
public function __construct(
ContainerInterface $settings,
State $state,
array $fields
) {
$this->settings = $settings;
$this->state = $state;
$this->fields = $fields;
}
//phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
public function renderMultiSelect($field, $key, $config, $value): string
{
if ($config['type'] !== 'ppcp-multiselect') {
return $field;
}
$options = [];
foreach ($config['options'] as $optionKey => $optionValue) {
$selected = (in_array($optionKey, $value, true)) ? 'selected="selected"' : '';
$options[] = '<option value="' . esc_attr($optionKey) . '" ' . $selected . '>' .
esc_html($optionValue) .
'</option>';
}
$html = sprintf(
'<select
multiple
class="%s"
name="%s"
>%s</select>',
implode(' ', $config['class']),
$key,
implode('', $options)
);
return $html;
}
//phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration.NoArgumentType
public function render()
{
$nonce = wp_create_nonce(SettingsListener::NONCE);
?>
<input type="hidden" name="ppcp-nonce" value="<?php echo esc_attr($nonce); ?>">
<?php
foreach ($this->fields as $field => $config) :
if (! in_array($this->state->currentState(), $config['screens'], true)) {
continue;
}
$value = $this->settings->has($field) ? $this->settings->get($field) : null;
$id = 'ppcp[' . $field . ']';
?>
<tr valign="top">
<th>
<label
for="<?php echo esc_attr($id); ?>"
><?php echo esc_html($config['title']); ?></label>
<?php if (isset($config['desc_tip']) && $config['desc_tip']) : ?>
<span
class="woocommerce-help-tip"
data-tip="<?php echo esc_attr($config['description']); ?>"
></span>
<?php unset($config['description']);
endif; ?>
</th>
<td><?php
$config['type'] === 'ppcp-text' ?
$this->renderText($config)
: woocommerce_form_field($id, $config, $value); ?></td>
</tr>
<?php endforeach;
}
private function renderText(array $config)
{
echo wp_kses_post($config['text']);
if (isset($config['hidden'])) {
$value = $this->settings->has($config['hidden']) ?
(string) $this->settings->get($config['hidden'])
: '';
echo '<input
type="hidden"
name="ppcp[' . esc_attr($config['hidden']) . ']"
value="' . esc_attr($value) . '"
>';
}
}
}

View file

@ -1,158 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
use Inpsyde\PayPalCommerce\Onboarding\Environment;
trait SettingsTrait
{
/**
* @var Environment
*/
private $environment;
private function defaultFields(): array
{
$isSandbox = ($this->environment) ? $this->environment->currentEnvironmentIs(Environment::SANDBOX) : false;
$sandbox = [
'type' => 'ppcp_info',
'title' => __('Sandbox'),
'text' => ($isSandbox) ? __('You are currently in the sandbox mode. Click Reset if you want to change your mode.', 'woocommerce-paypal-commerce-gateway') : __('You are in production mode. Click Reset if you want to change your mode.', 'woocommerce-paypal-commerce-gateway'),
];
return array_merge(
[
'enabled' => [
'title' => __('Enable/Disable', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable PayPal Payments', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'title' => [
'title' => __('Title', 'woocommerce-paypal-gateway'),
'type' => 'text',
'description' => __(
'This controls the title which the user sees during checkout.',
'woocommerce-paypal-gateway'
),
'default' => __('PayPal', 'woocommerce-paypal-gateway'),
'desc_tip' => true,
],
'description' => [
'title' => __('Description', 'woocommerce-paypal-gateway'),
'type' => 'text',
'desc_tip' => true,
'description' => __(
'This controls the description which the user sees during checkout.',
'woocommerce-paypal-gateway'
),
'default' => __(
'Pay via PayPal; you can pay with your credit card if you don\'t have a PayPal account.',
'woocommerce-paypal-gateway'
),
],
'account_settings' => [
'title' => __('Account Settings', 'woocommerce-paypal-gateway'),
'type' => 'title',
'description' => '',
],
'sandbox_on' => $sandbox,
'reset' => [
'type' => 'ppcp_reset',
],
],
$this->buttons()
);
}
private function buttons(): array
{
return [
'button_settings' => [
'title' => __('SmartButton Settings', 'woocommerce-paypal-gateway'),
'type' => 'title',
'description' => __(
'Customize the appearance of PayPal Payments on your site.',
'woocommerce-paypal-gateway'
),
],
'button_single_product_enabled' => [
'title' => __('Buttons on Single Product', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Single Product', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'button_mini_cart_enabled' => [
'title' => __('Buttons on Mini Cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Mini Cart', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'button_cart_enabled' => [
'title' => __('Buttons on Cart', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __('Enable on Cart', 'woocommerce-paypal-gateway'),
'default' => 'yes',
],
'button_color' => [
'title' => __('Color', 'woocommerce-paypal-gateway'),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'gold',
'desc_tip' => true,
'description' => __(
'Controls the background color of the primary button. Use "Gold" to leverage PayPal\'s recognition and preference, or change it to match your site design or aesthetic.',
'woocommerce-paypal-gateway'
),
'options' => [
'gold' => __('Gold (Recommended)', 'woocommerce-paypal-gateway'),
'blue' => __('Blue', 'woocommerce-paypal-gateway'),
'silver' => __('Silver', 'woocommerce-paypal-gateway'),
'black' => __('Black', 'woocommerce-paypal-gateway'),
],
],
'button_shape' => [
'title' => __('Shape', 'woocommerce-paypal-gateway'),
'type' => 'select',
'class' => 'wc-enhanced-select',
'default' => 'rect',
'desc_tip' => true,
'description' => __(
'The pill-shaped button\'s unique and powerful shape signifies PayPal in people\'s minds. Use the rectangular button as an alternative when pill-shaped buttons might pose design challenges.',
'woocommerce-paypal-gateway'
),
'options' => [
'pill' => __('Pill', 'woocommerce-paypal-gateway'),
'rect' => __('Rectangle', 'woocommerce-paypal-gateway'),
],
],
'disable_funding' => [
'title' => __('Disable funding sources', 'woocommerce-paypal-gateway'),
'type' => 'multiselect',
'class' => 'wc-enhanced-select',
'default' => [],
'desc_tip' => true,
'description' => __(
'By default all possible funding sources will be shown. You can disable some sources, if you wish.',
'woocommerce-paypal-gateway'
),
'options' => [
'card' => _x('Credit or debit cards', 'Name of payment method', 'woocommerce-paypal-gateway'),
'credit' => _x('PayPal Credit', 'Name of payment method', 'woocommerce-paypal-gateway'),
'venmo' => _x('Venmo', 'Name of payment method', 'woocommerce-paypal-gateway'),
'sepa' => _x('SEPA-Lastschrift', 'Name of payment method', 'woocommerce-paypal-gateway'),
'bancontact' => _x('Bancontact', 'Name of payment method', 'woocommerce-paypal-gateway'),
'eps' => _x('eps', 'Name of payment method', 'woocommerce-paypal-gateway'),
'giropay' => _x('giropay', 'Name of payment method', 'woocommerce-paypal-gateway'),
'ideal' => _x('iDEAL', 'Name of payment method', 'woocommerce-paypal-gateway'),
'mybank' => _x('MyBank', 'Name of payment method', 'woocommerce-paypal-gateway'),
'p24' => _x('Przelewy24', 'Name of payment method', 'woocommerce-paypal-gateway'),
'sofort' => _x('Sofort', 'Name of payment method', 'woocommerce-paypal-gateway'),
],
],
];
}
}

View file

@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\WcGateway\Settings;
class StartSettings implements SettingsFields
{
use SettingsTrait;
public function fields(): array
{
return [
'merchant_email' => [
'title' => __('PayPal Email', 'woocommerce-paypal-gateway'),
'type' => 'email',
'description' => __(
'Please enter the email address with which you want to receive payments.',
'woocommerce-paypal-gateway'
),
'default' => '',
'desc_tip' => true,
],
'sandbox_on' => [
'title' => __('Enable Sandbox', 'woocommerce-paypal-gateway'),
'type' => 'checkbox',
'label' => __(
'For testing your integration, you can enable the sandbox.',
'woocommerce-paypal-gateway'
),
'default' => 'no',
],
];
}
}

View file

@ -14,6 +14,7 @@ use Inpsyde\PayPalCommerce\WcGateway\Checkout\DisableGateways;
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGateway;
use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use Inpsyde\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use Interop\Container\ServiceProviderInterface;
use Psr\Container\ContainerInterface;
@ -29,32 +30,9 @@ class WcGatewayModule implements ModuleInterface
public function run(ContainerInterface $container)
{
add_filter(
'woocommerce_payment_gateways',
static function ($methods) use ($container): array {
$methods[] = $container->get('wcgateway.gateway');
return (array)$methods;
}
);
add_filter(
'woocommerce_available_payment_gateways',
static function ($methods) use ($container): array {
$disabler = $container->get('wcgateway.disabler');
/**
* @var DisableGateways $disabler
*/
return $disabler->handler((array)$methods);
}
);
add_action(
'admin_init',
function() use ($container) {
$resetGateway = $container->get('wcgateway.gateway.reset');
$resetGateway->listen();
}
);
$this->registerPaymentGateway($container);
$this->registerOrderFunctionality($container);
$this->registerColumns($container);
add_filter(
Repository::NOTICES_FILTER,
@ -76,7 +54,54 @@ class WcGatewayModule implements ModuleInterface
return $notices;
}
);
}
private function registerPaymentGateWay(ContainerInterface $container)
{
add_filter(
'woocommerce_payment_gateways',
static function ($methods) use ($container): array {
$methods[] = $container->get('wcgateway.gateway');
return (array)$methods;
}
);
add_action(
'woocommerce_settings_save_checkout',
static function () use ($container) {
$listener = $container->get('wcgateway.settings.listener');
$listener->listen();
}
);
add_filter(
'woocommerce_form_field',
static function ($field, $key, $args, $value) use ($container) {
$renderer = $container->get('wcgateway.settings.render');
/**
* @var SettingsRenderer $renderer
*/
return $renderer->renderMultiSelect($field, $key, $args, $value);
},
10,
4
);
add_filter(
'woocommerce_available_payment_gateways',
static function ($methods) use ($container): array {
$disabler = $container->get('wcgateway.disabler');
/**
* @var DisableGateways $disabler
*/
return $disabler->handler((array)$methods);
}
);
}
private function registerOrderFunctionality(ContainerInterface $container)
{
add_filter(
'woocommerce_order_actions',
static function ($orderActions): array {
@ -98,7 +123,10 @@ class WcGatewayModule implements ModuleInterface
$gateway->captureAuthorizedPayment($wcOrder);
}
);
}
private function registerColumns(ContainerInterface $container)
{
add_action(
'woocommerce_order_actions_start',
static function ($wcOrderId) use ($container) {

View file

@ -10,6 +10,7 @@ use Inpsyde\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
use Inpsyde\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
use Inpsyde\PayPalCommerce\WcGateway\Processor\OrderProcessor;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsFields;
use Inpsyde\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
use Mockery;
use function Brain\Monkey\Functions\expect;
@ -17,37 +18,11 @@ class WcGatewayTest extends TestCase
{
public function testFormFieldsAreSet()
{
$expectedFields = ['key' => 'value'];
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn($expectedFields);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
$onboardingRenderer
);
$this->assertEquals($testee->form_fields, $expectedFields);
}
public function testProcessPaymentSuccess() {
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$orderProcessor
->expects('process')
@ -60,7 +35,7 @@ class WcGatewayTest extends TestCase
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
@ -71,7 +46,10 @@ class WcGatewayTest extends TestCase
->with($orderId)
->andReturn($wcOrder);
global $woocommerce;
$woocommerce = Mockery::mock(\WooCommerce::class);
$result = $testee->process_payment($orderId);
unset($woocommerce);
$this->assertIsArray($result);
$this->assertEquals('success', $result['result']);
$this->assertEquals($result['redirect'], $wcOrder);
@ -80,16 +58,13 @@ class WcGatewayTest extends TestCase
public function testProcessPaymentOrderNotFound() {
$orderId = 1;
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
@ -100,7 +75,10 @@ class WcGatewayTest extends TestCase
->with($orderId)
->andReturn(false);
global $woocommerce;
$woocommerce = Mockery::mock(\WooCommerce::class);
$this->assertNull($testee->process_payment($orderId));
unset($woocommerce);
}
@ -109,10 +87,7 @@ class WcGatewayTest extends TestCase
$orderId = 1;
$wcOrder = Mockery::mock(\WC_Order::class);
$lastError = 'some-error';
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$orderProcessor
->expects('process')
@ -124,7 +99,7 @@ class WcGatewayTest extends TestCase
$authorizedOrderActionNotice = Mockery::mock(AuthorizeOrderActionNotice::class);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
@ -137,7 +112,10 @@ class WcGatewayTest extends TestCase
expect('wc_add_notice')
->with($lastError);
global $woocommerce;
$woocommerce = Mockery::mock(\WooCommerce::class);
$result = $testee->process_payment($orderId);
unset($woocommerce);
$this->assertNull($result);
}
@ -154,10 +132,7 @@ class WcGatewayTest extends TestCase
->with(WcGateway::CAPTURED_META_KEY, 'true');
$wcOrder
->expects('save');
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizedPaymentsProcessor
@ -174,7 +149,7 @@ class WcGatewayTest extends TestCase
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
@ -200,10 +175,7 @@ class WcGatewayTest extends TestCase
->with(WcGateway::CAPTURED_META_KEY, 'true');
$wcOrder
->expects('save');
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizedPaymentsProcessor
@ -219,7 +191,7 @@ class WcGatewayTest extends TestCase
->with(AuthorizeOrderActionNotice::ALREADY_CAPTURED);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,
@ -238,10 +210,7 @@ class WcGatewayTest extends TestCase
public function testCaptureAuthorizedPaymentNoActionableFailures($lastStatus, $expectedMessage) {
$wcOrder = Mockery::mock(\WC_Order::class);
$settingsFields = Mockery::mock(SettingsFields::class);
$settingsFields
->expects('fields')
->andReturn([]);
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
$orderProcessor = Mockery::mock(OrderProcessor::class);
$authorizedPaymentsProcessor = Mockery::mock(AuthorizedPaymentsProcessor::class);
$authorizedPaymentsProcessor
@ -257,7 +226,7 @@ class WcGatewayTest extends TestCase
->with($expectedMessage);
$onboardingRenderer = Mockery::mock(OnboardingRenderer::class);
$testee = new WcGateway(
$settingsFields,
$settingsRenderer,
$orderProcessor,
$authorizedPaymentsProcessor,
$authorizedOrderActionNotice,

View file

@ -13,6 +13,7 @@ use Inpsyde\PayPalCommerce\ApiClient\Repository\CartRepository;
use Inpsyde\PayPalCommerce\Session\SessionHandler;
use Inpsyde\PayPalCommerce\TestCase;
use Inpsyde\PayPalCommerce\WcGateway\Gateway\WcGateway;
use Inpsyde\Woocommerce\Logging\WoocommerceLoggingModule;
use Mockery;
class OrderProcessorTest extends TestCase
@ -75,7 +76,8 @@ class OrderProcessorTest extends TestCase
$cart = Mockery::mock(\WC_Cart::class);
$cart
->expects('empty_cart');
$woocommerce = (object) ['cart' => $cart];
$woocommerce = Mockery::mock(\WooCommerce::class);
$woocommerce->cart = $cart;
$wcOrder
->expects('update_meta_data')
@ -158,7 +160,8 @@ class OrderProcessorTest extends TestCase
$cart = Mockery::mock(\WC_Cart::class);
$cart
->expects('empty_cart');
$woocommerce = (object) ['cart' => $cart];
$woocommerce = Mockery::mock(\WooCommerce::class);
$woocommerce->cart = $cart;
$wcOrder
->expects('update_meta_data')
@ -218,7 +221,8 @@ class OrderProcessorTest extends TestCase
);
$cart = Mockery::mock(\WC_Cart::class);
$woocommerce = (object) ['cart' => $cart];
$woocommerce = Mockery::mock(\WooCommerce::class);
$woocommerce->cart = $cart;
$wcOrder
->expects('update_meta_data')