add webhook

This commit is contained in:
David Remer 2020-07-06 11:04:06 +03:00
parent a740e866fe
commit 33a84b19cb
11 changed files with 278 additions and 1 deletions

View file

@ -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": {

View file

@ -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
}

View file

@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
return [
];

View file

@ -0,0 +1,11 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
use Dhii\Modular\Module\ModuleInterface;
return static function (): ModuleInterface {
return new WebhookModule();
};

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="vendor/autoload.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./src</directory>
</whitelist>
</filter>
<testsuites>
<testsuite name="unit">
<directory suffix="Test.php">./tests/PHPUnit</directory>
</testsuite>
</testsuites>
</phpunit>

View file

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
use Inpsyde\PayPalCommerce\Webhooks\Handler\PaymentCaptureCompleted;
use Psr\Container\ContainerInterface;
return [
'webhook.registrar' => 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(),
];
}
];

View file

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks\Handler;
class PaymentCaptureCompleted implements RequestHandler
{
public function eventType(): string
{
return 'PAYMENT.CAPTURE.COMPLETED';
}
public function responsibleForRequest(\WP_REST_Request $request): bool
{
return true;
}
public function handleRequest(\WP_REST_Request $request): \WP_REST_Response
{
return new \WP_REST_Response();
}
}

View file

@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks\Handler;
interface RequestHandler
{
public function eventType() : string;
public function responsibleForRequest(\WP_REST_Request $request) : bool;
public function handleRequest(\WP_REST_Request $request) : \WP_REST_Response;
}

View file

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
use Inpsyde\PayPalCommerce\Webhooks\Handler\RequestHandler;
class IncomingWebhookEndpoint
{
public const NAMESPACE = 'paypal/v1/';
public const ROUTE = 'incoming';
private $handlers;
public function __construct(RequestHandler ...$handlers)
{
$this->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
);
}
}

View file

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
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;
class WebhookModule implements ModuleInterface
{
public function setup(): ServiceProviderInterface
{
return new ServiceProvider(
require __DIR__ . '/../services.php',
require __DIR__ . '/../extensions.php'
);
}
public function run(ContainerInterface $container)
{
add_action(
'rest_init',
function() use ($container) {
$endpoint = $container->get('webhook.endpoint.controller');
/**
* @var IncomingWebhookEndpoint $endpoint
*/
$endpoint->register();
}
);
}
}

View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Inpsyde\PayPalCommerce\Webhooks;
use Inpsyde\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
use Inpsyde\PayPalCommerce\ApiClient\Exception\RuntimeException;
use Inpsyde\PayPalCommerce\ApiClient\Factory\WebhookFactory;
class WebhookRegistrar
{
private $webhookFactory;
private $endpoint;
private $restEndpoint;
public function __construct(
WebhookFactory $webhookFactory,
WebhookEndpoint $endpoint,
IncomingWebhookEndpoint $restEndpoint
) {
$this->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;
}
}
}