From 33a84b19cba3764100e5cf1b26dd8216cb21126a Mon Sep 17 00:00:00 2001 From: David Remer Date: Mon, 6 Jul 2020 11:04:06 +0300 Subject: [PATCH] add webhook --- composer.json | 3 +- modules.local/ppcp-webhooks/composer.json | 27 +++++++++ modules.local/ppcp-webhooks/extensions.php | 9 +++ modules.local/ppcp-webhooks/module.php | 11 ++++ modules.local/ppcp-webhooks/phpunit.xml.dist | 20 +++++++ modules.local/ppcp-webhooks/services.php | 31 ++++++++++ .../src/Handler/PaymentCaptureCompleted.php | 25 ++++++++ .../src/Handler/RequestHandler.php | 15 +++++ .../src/IncomingWebhookEndpoint.php | 58 +++++++++++++++++++ .../ppcp-webhooks/src/WebhookModule.php | 39 +++++++++++++ .../ppcp-webhooks/src/WebhookRegistrar.php | 41 +++++++++++++ 11 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 modules.local/ppcp-webhooks/composer.json create mode 100644 modules.local/ppcp-webhooks/extensions.php create mode 100644 modules.local/ppcp-webhooks/module.php create mode 100644 modules.local/ppcp-webhooks/phpunit.xml.dist create mode 100644 modules.local/ppcp-webhooks/services.php create mode 100644 modules.local/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php create mode 100644 modules.local/ppcp-webhooks/src/Handler/RequestHandler.php create mode 100644 modules.local/ppcp-webhooks/src/IncomingWebhookEndpoint.php create mode 100644 modules.local/ppcp-webhooks/src/WebhookModule.php create mode 100644 modules.local/ppcp-webhooks/src/WebhookRegistrar.php diff --git a/composer.json b/composer.json index 639fecdff..907493905 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,8 @@ "Inpsyde\\PayPalCommerce\\Button\\": "modules.local/ppcp-button/src/", "Inpsyde\\PayPalCommerce\\WcGateway\\": "modules.local/ppcp-wc-gateway/src/", "Inpsyde\\PayPalCommerce\\Onboarding\\": "modules.local/ppcp-onboarding/src/", - "Inpsyde\\Woocommerce\\Logging\\": "modules.local/woocommerce-logging/src/" + "Inpsyde\\Woocommerce\\Logging\\": "modules.local/woocommerce-logging/src/", + "Inpsyde\\Woocommerce\\Webhooks\\": "modules.local/ppcp-webhooks/src/" } }, "autoload-dev": { diff --git a/modules.local/ppcp-webhooks/composer.json b/modules.local/ppcp-webhooks/composer.json new file mode 100644 index 000000000..be4c9a9fd --- /dev/null +++ b/modules.local/ppcp-webhooks/composer.json @@ -0,0 +1,27 @@ +{ + "name": "inpsyde/ppcp-webhooks", + "type": "inpsyde-module", + "require": { + "dhii/module-interface": "0.2.x-dev" + }, + "autoload": { + "psr-4": { + "Inpsyde\\PayPalCommerce\\Webhooks\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Inpsyde\\PayPalCommerce\\Webhooks\\": "tests/PHPUnit" + } + }, + "scripts": { + "unit": "./vendor/bin/phpunit --coverage-html build/coverage-report" + }, + "require-dev": { + "phpunit/phpunit": "^9.1", + "brain/monkey": "^2.4", + "inpsyde/php-coding-standards": "^1" + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/modules.local/ppcp-webhooks/extensions.php b/modules.local/ppcp-webhooks/extensions.php new file mode 100644 index 000000000..ca4be65b8 --- /dev/null +++ b/modules.local/ppcp-webhooks/extensions.php @@ -0,0 +1,9 @@ + + + + + ./src + + + + + ./tests/PHPUnit + + + diff --git a/modules.local/ppcp-webhooks/services.php b/modules.local/ppcp-webhooks/services.php new file mode 100644 index 000000000..177b2ff24 --- /dev/null +++ b/modules.local/ppcp-webhooks/services.php @@ -0,0 +1,31 @@ + function(ContainerInterface $container) : WebhookRegistrar { + $factory = $container->get('api.factory.webhook'); + $endpoint = $container->get('api.endpoint.webhook'); + $restEndpoint = $container->get('webhook.endpoint.controller'); + return new WebhookRegistrar( + $factory, + $endpoint, + $restEndpoint + ); + }, + 'webhook.endpoint.controller' => function(ContainerInterface $container) : IncomingWebhookEndpoint { + $handler = $container->get('webhook.endpoint.handler'); + return new IncomingWebhookEndpoint(... $handler); + }, + 'webhook.endpoint.handler' => function(ContainerInterface $container) : array { + return [ + new PaymentCaptureCompleted(), + ]; + } +]; diff --git a/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php new file mode 100644 index 000000000..047d6eca2 --- /dev/null +++ b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php @@ -0,0 +1,25 @@ +handlers = $handlers; + } + + public function register() : bool + { + return (bool) register_rest_route( + self::NAMESPACE, + self::ROUTE, + [ + 'methods' => [ + 'GET', + ], + 'callback' => [ + $this, + 'handleRequest', + ], + ] + ); + } + + public function handleRequest(\WP_REST_Request $request) : \WP_REST_Response { + + foreach ($this->handlers as $handler) { + if ($handler->responsibleForRequest($request)) { + return $handler->handleRequest($request); + } + } + } + + public function url() : string { + return rest_url(self::NAMESPACE . self::ROUTE ); + } + + public function handledEventTypes() : array { + return array_map( + function(RequestHandler $handler) : string { + return $handler->eventType(); + }, + $this->handlers + ); + } +} diff --git a/modules.local/ppcp-webhooks/src/WebhookModule.php b/modules.local/ppcp-webhooks/src/WebhookModule.php new file mode 100644 index 000000000..835a56bca --- /dev/null +++ b/modules.local/ppcp-webhooks/src/WebhookModule.php @@ -0,0 +1,39 @@ +get('webhook.endpoint.controller'); + /** + * @var IncomingWebhookEndpoint $endpoint + */ + $endpoint->register(); + } + ); + + } +} diff --git a/modules.local/ppcp-webhooks/src/WebhookRegistrar.php b/modules.local/ppcp-webhooks/src/WebhookRegistrar.php new file mode 100644 index 000000000..060c4a355 --- /dev/null +++ b/modules.local/ppcp-webhooks/src/WebhookRegistrar.php @@ -0,0 +1,41 @@ +webhookFactory = $webhookFactory; + $this->endpoint = $endpoint; + $this->restEndpoint = $restEndpoint; + } + + public function register() : bool + { + $webhook = $this->webhookFactory->forUrlAndEvents( + $this->restEndpoint->url(), + $this->restEndpoint->handledEventTypes() + ); + + try { + $created = $this->endpoint->create($webhook); + return ! empty($created->id()); + } catch (RuntimeException $error) { + return false; + } + } +} \ No newline at end of file