@@ -39,30 +71,54 @@ const TabOverview = () => {
title={ __( 'Features', 'woocommerce-paypal-payments' ) }
description={
-
{ __( 'Enable additional features…' ) }
-
{ __( 'Click Refresh…' ) }
-
}
- contentItems={ featuresDefault.map( ( feature ) => (
+ contentItems={ features.map( ( feature ) => (
) ) }
@@ -133,7 +189,6 @@ const featuresDefault = [
'Advanced Credit and Debit Cards',
'woocommerce-paypal-payments'
),
- featureStatus: true,
description: __(
'Process major credit and debit cards including Visa, Mastercard, American Express and Discover.',
'woocommerce-paypal-payments'
@@ -181,7 +236,6 @@ const featuresDefault = [
'Let customers pay using their Google Pay wallet.',
'woocommerce-paypal-payments'
),
- featureStatus: true,
buttons: [
{
type: 'secondary',
diff --git a/modules/ppcp-settings/resources/js/data/common/action-types.js b/modules/ppcp-settings/resources/js/data/common/action-types.js
index 34e831508..ac08cdcf7 100644
--- a/modules/ppcp-settings/resources/js/data/common/action-types.js
+++ b/modules/ppcp-settings/resources/js/data/common/action-types.js
@@ -23,4 +23,5 @@ export default {
DO_SANDBOX_LOGIN: 'COMMON:DO_SANDBOX_LOGIN',
DO_PRODUCTION_LOGIN: 'COMMON:DO_PRODUCTION_LOGIN',
DO_REFRESH_MERCHANT: 'COMMON:DO_REFRESH_MERCHANT',
+ DO_REFRESH_FEATURES: 'DO_REFRESH_FEATURES',
};
diff --git a/modules/ppcp-settings/resources/js/data/common/actions.js b/modules/ppcp-settings/resources/js/data/common/actions.js
index 7dd13206e..1982d7f42 100644
--- a/modules/ppcp-settings/resources/js/data/common/actions.js
+++ b/modules/ppcp-settings/resources/js/data/common/actions.js
@@ -7,7 +7,7 @@
* @file
*/
-import { select } from '@wordpress/data';
+import { dispatch, select } from '@wordpress/data';
import ACTION_TYPES from './action-types';
import { STORE_NAME } from './constants';
@@ -189,3 +189,20 @@ export const connectViaIdAndSecret = function* () {
export const refreshMerchantData = function* () {
return yield { type: ACTION_TYPES.DO_REFRESH_MERCHANT };
};
+
+/**
+ * Side effect.
+ * Purges all feature status data via a REST request.
+ * Refreshes the merchant data via a REST request.
+ *
+ * @return {Action} The action.
+ */
+export const refreshFeatureStatuses = function* () {
+ const result = yield { type: ACTION_TYPES.DO_REFRESH_FEATURES };
+
+ if ( result && result.success ) {
+ return yield dispatch( STORE_NAME ).refreshMerchantData();
+ }
+
+ return result;
+};
diff --git a/modules/ppcp-settings/resources/js/data/common/constants.js b/modules/ppcp-settings/resources/js/data/common/constants.js
index 9499ef069..c67b1fef0 100644
--- a/modules/ppcp-settings/resources/js/data/common/constants.js
+++ b/modules/ppcp-settings/resources/js/data/common/constants.js
@@ -53,3 +53,14 @@ export const REST_MANUAL_CONNECTION_PATH = '/wc/v3/wc_paypal/connect_manual';
* @type {string}
*/
export const REST_CONNECTION_URL_PATH = '/wc/v3/wc_paypal/login_link';
+
+/**
+ * REST path to refresh the feature status.
+ *
+ * Used by: Controls
+ * See: RefreshFeatureStatusEndpoint.php
+ *
+ * @type {string}
+ */
+export const REST_REFRESH_FEATURES_PATH =
+ '/wc/v3/wc_paypal/refresh-feature-status';
diff --git a/modules/ppcp-settings/resources/js/data/common/controls.js b/modules/ppcp-settings/resources/js/data/common/controls.js
index 7845f335f..e095d6acb 100644
--- a/modules/ppcp-settings/resources/js/data/common/controls.js
+++ b/modules/ppcp-settings/resources/js/data/common/controls.js
@@ -16,6 +16,7 @@ import {
REST_MANUAL_CONNECTION_PATH,
REST_CONNECTION_URL_PATH,
REST_HYDRATE_MERCHANT_PATH,
+ REST_REFRESH_FEATURES_PATH,
} from './constants';
import ACTION_TYPES from './action-types';
@@ -121,4 +122,27 @@ export const controls = {
return result;
},
+
+ async [ ACTION_TYPES.DO_REFRESH_FEATURES ]() {
+ let result = null;
+
+ try {
+ result = await apiFetch( {
+ path: REST_REFRESH_FEATURES_PATH,
+ method: 'POST',
+ } );
+
+ if ( result.success ) {
+ result = await dispatch( STORE_NAME ).refreshMerchantData();
+ }
+ } catch ( e ) {
+ result = {
+ success: false,
+ error: e,
+ message: e.message,
+ };
+ }
+
+ return result;
+ },
};
diff --git a/modules/ppcp-settings/services.php b/modules/ppcp-settings/services.php
index c1eeca241..349c13350 100644
--- a/modules/ppcp-settings/services.php
+++ b/modules/ppcp-settings/services.php
@@ -17,6 +17,7 @@
use WooCommerce\PayPalCommerce\Settings\Endpoint\ConnectManualRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\LoginLinkRestEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\OnboardingRestEndpoint;
+use WooCommerce\PayPalCommerce\Settings\Endpoint\RefreshFeatureStatusEndpoint;
use WooCommerce\PayPalCommerce\Settings\Endpoint\SwitchSettingsUiEndpoint;
use WooCommerce\PayPalCommerce\Settings\Service\ConnectionUrlGenerator;
use WooCommerce\PayPalCommerce\Settings\Service\OnboardingUrlManager;
@@ -70,6 +71,13 @@
'settings.rest.common' => static function ( ContainerInterface $container ) : CommonRestEndpoint {
return new CommonRestEndpoint( $container->get( 'settings.data.common' ) );
},
+ 'settings.rest.refresh_feature_status' => static function ( ContainerInterface $container ) : RefreshFeatureStatusEndpoint {
+ return new RefreshFeatureStatusEndpoint(
+ $container->get( 'wcgateway.settings' ),
+ new Cache( 'ppcp-timeout' ),
+ $container->get( 'woocommerce.logger.woocommerce' )
+ );
+ },
'settings.rest.connect_manual' => static function ( ContainerInterface $container ) : ConnectManualRestEndpoint {
return new ConnectManualRestEndpoint(
$container->get( 'api.paypal-host-production' ),
diff --git a/modules/ppcp-settings/src/Endpoint/CommonRestEndpoint.php b/modules/ppcp-settings/src/Endpoint/CommonRestEndpoint.php
index 3c0131759..7524e7e31 100644
--- a/modules/ppcp-settings/src/Endpoint/CommonRestEndpoint.php
+++ b/modules/ppcp-settings/src/Endpoint/CommonRestEndpoint.php
@@ -206,6 +206,11 @@ protected function add_merchant_info( array $extra_data ) : array {
$this->merchant_info_map
);
+ $extra_data['merchant'] = apply_filters(
+ 'woocommerce_paypal_payments_rest_common_merchant_data',
+ $extra_data['merchant'],
+ );
+
return $extra_data;
}
diff --git a/modules/ppcp-settings/src/Endpoint/RefreshFeatureStatusEndpoint.php b/modules/ppcp-settings/src/Endpoint/RefreshFeatureStatusEndpoint.php
new file mode 100644
index 000000000..d8fc2760e
--- /dev/null
+++ b/modules/ppcp-settings/src/Endpoint/RefreshFeatureStatusEndpoint.php
@@ -0,0 +1,132 @@
+settings = $settings;
+ $this->cache = $cache;
+ $this->logger = $logger;
+ }
+
+ /**
+ * Configure REST API routes.
+ */
+ public function register_routes() {
+ register_rest_route(
+ $this->namespace,
+ '/' . $this->rest_base,
+ array(
+ array(
+ 'methods' => WP_REST_Server::EDITABLE,
+ 'callback' => array( $this, 'refresh_status' ),
+ 'permission_callback' => array( $this, 'check_permission' ),
+ ),
+ )
+ );
+ }
+
+ /**
+ * Handles the refresh status request.
+ *
+ * @param WP_REST_Request $request Full data about the request.
+ * @return WP_REST_Response
+ */
+ public function refresh_status( WP_REST_Request $request ): WP_REST_Response {
+ $now = time();
+ $last_request_time = $this->cache->get( self::CACHE_KEY ) ?: 0;
+ $seconds_missing = $last_request_time + self::TIMEOUT - $now;
+
+ if ( $seconds_missing > 0 ) {
+ return $this->return_error(
+ sprintf(
+ // translators: %1$s is the number of seconds remaining.
+ __( 'Wait %1$s seconds before trying again.', 'woocommerce-paypal-payments' ),
+ $seconds_missing
+ )
+ );
+ }
+
+ $this->cache->set( self::CACHE_KEY, $now, self::TIMEOUT );
+
+ do_action( 'woocommerce_paypal_payments_clear_apm_product_status', $this->settings );
+
+ $this->logger->info( 'Feature status refreshed successfully' );
+
+ return $this->return_success(
+ array(
+ 'message' => __( 'Feature status refreshed successfully.', 'woocommerce-paypal-payments' ),
+ )
+ );
+ }
+}
diff --git a/modules/ppcp-settings/src/SettingsModule.php b/modules/ppcp-settings/src/SettingsModule.php
index 7cb55bb02..f2d7267e0 100644
--- a/modules/ppcp-settings/src/SettingsModule.php
+++ b/modules/ppcp-settings/src/SettingsModule.php
@@ -181,6 +181,7 @@ static function () use ( $container ) : void {
$container->get( 'settings.rest.common' ),
$container->get( 'settings.rest.connect_manual' ),
$container->get( 'settings.rest.login_link' ),
+ $container->get( 'settings.rest.refresh_feature_status' ),
);
foreach ( $endpoints as $endpoint ) {
diff --git a/modules/ppcp-wc-gateway/src/WCGatewayModule.php b/modules/ppcp-wc-gateway/src/WCGatewayModule.php
index 8c807474e..f754a3cbe 100644
--- a/modules/ppcp-wc-gateway/src/WCGatewayModule.php
+++ b/modules/ppcp-wc-gateway/src/WCGatewayModule.php
@@ -13,6 +13,7 @@
use Psr\Log\LoggerInterface;
use Throwable;
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
+use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\Orders;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
@@ -547,6 +548,33 @@ function( string $installed_plugin_version ) use ( $c ) {
}
);
+ add_filter(
+ 'woocommerce_paypal_payments_rest_common_merchant_data',
+ function( array $merchant_data ) use ( $c ): array {
+ if ( ! isset( $merchant_data['features'] ) ) {
+ $merchant_data['features'] = array();
+ }
+
+ $billing_agreements_endpoint = $c->get( 'api.endpoint.billing-agreements' );
+ assert( $billing_agreements_endpoint instanceof BillingAgreementsEndpoint );
+
+ $reference_transactions_enabled = $billing_agreements_endpoint->reference_transaction_enabled();
+ $merchant_data['features']['save_paypal_and_venmo'] = array(
+ 'enabled' => $reference_transactions_enabled,
+ );
+
+ $dcc_product_status = $c->get( 'wcgateway.helper.dcc-product-status' );
+ assert( $dcc_product_status instanceof DCCProductStatus );
+
+ $dcc_enabled = $dcc_product_status->dcc_is_active();
+ $merchant_data['features']['advanced_credit_and_debit_cards'] = array(
+ 'enabled' => $dcc_enabled,
+ );
+
+ return $merchant_data;
+ }
+ );
+
return true;
}