diff --git a/modules/ppcp-webhooks/extensions.php b/modules/ppcp-webhooks/extensions.php index 0b2fa379d..80a99909f 100644 --- a/modules/ppcp-webhooks/extensions.php +++ b/modules/ppcp-webhooks/extensions.php @@ -15,7 +15,7 @@ use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage; return array( 'wcgateway.settings.fields' => static function ( $container, array $fields ): array { $status_page_fields = array( - 'webhooks_list' => array( + 'webhooks_list' => array( 'title' => __( 'Subscribed webhooks', 'woocommerce-paypal-payments' ), 'type' => 'ppcp-table', 'screens' => array( @@ -29,6 +29,18 @@ return array( return $container->get( 'webhook.status.registered-webhooks-data' ); }, ), + 'webhooks_resubscribe' => array( + 'title' => __( 'Resubscribe webhooks', 'woocommerce-paypal-payments' ), + 'type' => 'ppcp-text', + 'text' => '', + 'screens' => array( + State::STATE_PROGRESSIVE, + State::STATE_ONBOARDED, + ), + 'requirements' => array(), + 'gateway' => WebhooksStatusPage::ID, + 'description' => __( 'Click to remove the current webhook subscription and subscribe again, for example, if the website domain or URL structure changed.', 'woocommerce-paypal-payments' ), + ), ); return array_merge( $fields, $status_page_fields ); diff --git a/modules/ppcp-webhooks/resources/js/status-page.js b/modules/ppcp-webhooks/resources/js/status-page.js index 7eab2654d..e10eec9b3 100644 --- a/modules/ppcp-webhooks/resources/js/status-page.js +++ b/modules/ppcp-webhooks/resources/js/status-page.js @@ -1,6 +1,42 @@ document.addEventListener( 'DOMContentLoaded', () => { + const resubscribeBtn = jQuery(PayPalCommerceGatewayWebhooksStatus.resubscribe.button); + resubscribeBtn.click(async () => { + resubscribeBtn.prop('disabled', true); + + const response = await fetch( + PayPalCommerceGatewayWebhooksStatus.resubscribe.endpoint, + { + method: 'POST', + headers: { + 'content-type': 'application/json' + }, + body: JSON.stringify( + { + nonce: PayPalCommerceGatewayWebhooksStatus.resubscribe.nonce, + } + ) + } + ); + + const reportError = error => { + const msg = PayPalCommerceGatewayWebhooksStatus.resubscribe.failureMessage + ' ' + error; + alert(msg); + } + + if (!response.ok) { + try { + const result = await response.json(); + reportError(result.data); + } catch (exc) { + console.error(exc); + reportError(response.status); + } + } + + window.location.reload(); + }); } ); diff --git a/modules/ppcp-webhooks/services.php b/modules/ppcp-webhooks/services.php index 06f239012..e57adacc8 100644 --- a/modules/ppcp-webhooks/services.php +++ b/modules/ppcp-webhooks/services.php @@ -13,6 +13,7 @@ use Exception; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook; use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets; +use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint; use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderApproved; use WooCommerce\PayPalCommerce\Webhooks\Handler\CheckoutOrderCompleted; use WooCommerce\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted; @@ -112,6 +113,16 @@ return array( ); }, + 'webhook.endpoint.resubscribe' => static function ( $container ) : ResubscribeEndpoint { + $registrar = $container->get( 'webhook.registrar' ); + $request_data = $container->get( 'button.request-data' ); + + return new ResubscribeEndpoint( + $registrar, + $request_data + ); + }, + 'webhook.module-url' => static function ( $container ): string { return plugins_url( '/modules/ppcp-webhooks/', diff --git a/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php b/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php new file mode 100644 index 000000000..b504cc38a --- /dev/null +++ b/modules/ppcp-webhooks/src/Endpoint/class-resubscribeendpoint.php @@ -0,0 +1,79 @@ +registrar = $registrar; + $this->request_data = $request_data; + } + + /** + * Returns the nonce for the endpoint. + * + * @return string + */ + public static function nonce(): string { + return self::ENDPOINT; + } + + /** + * Handles the incoming request. + */ + public function handle_request() { + try { + // Validate nonce. + $this->request_data->read_request( $this->nonce() ); + + $this->registrar->unregister(); + + if ( ! $this->registrar->register() ) { + wp_send_json_error( 'Webhook subscription failed.', 500 ); + return false; + } + + wp_send_json_success(); + return true; + } catch ( Exception $error ) { + wp_send_json_error( $error->getMessage(), 403 ); + return false; + } + } +} diff --git a/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php b/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php index 8fa1c72aa..90fa02086 100644 --- a/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php +++ b/modules/ppcp-webhooks/src/Status/Assets/class-webhooksstatuspageassets.php @@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Assets; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; +use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint; /** * Class WebhooksStatusPageAssets @@ -69,7 +70,14 @@ class WebhooksStatusPageAssets { * @return array */ public function get_script_data() { - return array(); + return array( + 'resubscribe' => array( + 'endpoint' => home_url( \WC_AJAX::get_endpoint( ResubscribeEndpoint::ENDPOINT ) ), + 'nonce' => wp_create_nonce( ResubscribeEndpoint::nonce() ), + 'button' => '.ppcp-webhooks-resubscribe', + 'failureMessage' => __( 'Operation failed. Check WooCommerce logs for more details.', 'woocommerce-paypal-payments' ), + ), + ); } /** diff --git a/modules/ppcp-webhooks/src/class-webhookmodule.php b/modules/ppcp-webhooks/src/class-webhookmodule.php index efc1497bb..ed464b993 100644 --- a/modules/ppcp-webhooks/src/class-webhookmodule.php +++ b/modules/ppcp-webhooks/src/class-webhookmodule.php @@ -16,6 +16,7 @@ use Interop\Container\ServiceProviderInterface; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use WooCommerce\PayPalCommerce\WcGateway\Assets\WebhooksStatusPageAssets; +use WooCommerce\PayPalCommerce\Webhooks\Endpoint\ResubscribeEndpoint; use WooCommerce\PayPalCommerce\Webhooks\Status\WebhooksStatusPage; /** @@ -83,6 +84,16 @@ class WebhookModule implements ModuleInterface { } ); + add_action( + 'wc_ajax_' . ResubscribeEndpoint::ENDPOINT, + static function () use ( $container ) { + $endpoint = $container->get( 'webhook.endpoint.resubscribe' ); + assert( $endpoint instanceof ResubscribeEndpoint ); + + $endpoint->handle_request(); + } + ); + $page_id = $container->get( 'wcgateway.current-ppcp-settings-page-id' ); if ( WebhooksStatusPage::ID === $page_id ) { $GLOBALS['hide_save_button'] = true;