diff --git a/modules.local/ppcp-webhooks/services.php b/modules.local/ppcp-webhooks/services.php index a65330d81..6a26501ec 100644 --- a/modules.local/ppcp-webhooks/services.php +++ b/modules.local/ppcp-webhooks/services.php @@ -6,6 +6,7 @@ namespace Inpsyde\PayPalCommerce\Webhooks; use Inpsyde\PayPalCommerce\Webhooks\Handler\CheckoutOrderCompleted; use Inpsyde\PayPalCommerce\Webhooks\Handler\PaymentCaptureRefunded; +use Inpsyde\PayPalCommerce\Webhooks\Handler\PaymentCaptureReversed; use Psr\Container\ContainerInterface; return [ @@ -33,6 +34,7 @@ return [ return [ new CheckoutOrderCompleted($logger), new PaymentCaptureRefunded($logger), + new PaymentCaptureReversed($logger), ]; } ]; diff --git a/modules.local/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php b/modules.local/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php index 34205ef2c..505f6249b 100644 --- a/modules.local/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php +++ b/modules.local/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php @@ -14,14 +14,14 @@ class CheckoutOrderCompleted implements RequestHandler $this->logger = $logger; } - public function eventType(): string + public function eventTypes(): array { - return 'CHECKOUT.ORDER.COMPLETED'; + return ['CHECKOUT.ORDER.COMPLETED']; } public function responsibleForRequest(\WP_REST_Request $request): bool { - return $request['event_type'] === $this->eventType(); + return in_array($request['event_type'], $this->eventTypes(), true); } public function handleRequest(\WP_REST_Request $request): \WP_REST_Response diff --git a/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php index b00c13508..a8fdc80d8 100644 --- a/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php +++ b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php @@ -14,14 +14,14 @@ class PaymentCaptureRefunded implements RequestHandler $this->logger = $logger; } - public function eventType(): string + public function eventTypes(): array { - return 'PAYMENT.CAPTURE.REFUNDED'; + return ['PAYMENT.CAPTURE.REFUNDED']; } public function responsibleForRequest(\WP_REST_Request $request): bool { - return $request['event_type'] === $this->eventType(); + return in_array($request['event_type'], $this->eventTypes(), true); } public function handleRequest(\WP_REST_Request $request): \WP_REST_Response diff --git a/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureReversed.php b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureReversed.php new file mode 100644 index 000000000..53231b966 --- /dev/null +++ b/modules.local/ppcp-webhooks/src/Handler/PaymentCaptureReversed.php @@ -0,0 +1,95 @@ +logger = $logger; + } + + public function eventTypes(): array + { + return [ + 'PAYMENT.CAPTURE.REVERSED', + 'PAYMENT.ORDER.CANCELLED', + 'PAYMENT.CAPTURE.DENIED', + ]; + } + + public function responsibleForRequest(\WP_REST_Request $request): bool + { + return in_array($request['event_type'], $this->eventTypes(), true); + } + + public function handleRequest(\WP_REST_Request $request): \WP_REST_Response + { + $response = ['success' => false]; + $orderId = isset($request['resource']['custom_id']) ? (int) $request['resource']['custom_id'] : 0; + if (! $orderId) { + $message = sprintf( + // translators: %s is the PayPal webhook Id. + __('No order for webhook event %s was found.', 'woocommerce-paypal-commerce-gateway'), + isset($request['id']) ? $request['id'] : '' + ); + $this->logger->log( + 'warning', + $message, + [ + 'request' => $request, + ] + ); + $response['message'] = $message; + return rest_ensure_response($response); + } + + $wcOrder = wc_get_order($orderId); + if (! is_a($wcOrder, \WC_Order::class)) { + $message = sprintf( + // translators: %s is the PayPal refund Id. + __('Order for PayPal refund %s not found.', 'woocommerce-paypal-commerce-gateway'), + isset($request['resource']['id']) ? $request['resource']['id'] : '' + ); + $this->logger->log( + 'warning', + $message, + [ + 'request' => $request, + ] + ); + $response['message'] = $message; + return rest_ensure_response($response); + } + + /** + * @var \WC_Order $wcOrder + */ + $response['success'] = (bool) $wcOrder->update_status('cancelled'); + + $message = $response['success'] ? sprintf( + //translators: %1$s is the order id. + __('Order %1$s has been cancelled through PayPal' , 'woocommerce-paypal-commerce-gateway'), + (string) $wcOrder->get_id() + ) : sprintf( + //translators: %1$s is the order id. + __('Failed to cancel order %1$s through PayPal' , 'woocommerce-paypal-commerce-gateway'), + (string) $wcOrder->get_id() + ); + $this->logger->log( + $response['success'] ? 'info' : 'warning', + $message, + [ + 'request' => $request, + 'order' => $wcOrder, + ] + ); + return rest_ensure_response($response); + } +} \ No newline at end of file diff --git a/modules.local/ppcp-webhooks/src/Handler/RequestHandler.php b/modules.local/ppcp-webhooks/src/Handler/RequestHandler.php index 885b37208..7743db5e2 100644 --- a/modules.local/ppcp-webhooks/src/Handler/RequestHandler.php +++ b/modules.local/ppcp-webhooks/src/Handler/RequestHandler.php @@ -7,7 +7,7 @@ namespace Inpsyde\PayPalCommerce\Webhooks\Handler; interface RequestHandler { - public function eventType() : string; + public function eventTypes() : array; public function responsibleForRequest(\WP_REST_Request $request) : bool; diff --git a/modules.local/ppcp-webhooks/src/IncomingWebhookEndpoint.php b/modules.local/ppcp-webhooks/src/IncomingWebhookEndpoint.php index da490e0dd..669efad2b 100644 --- a/modules.local/ppcp-webhooks/src/IncomingWebhookEndpoint.php +++ b/modules.local/ppcp-webhooks/src/IncomingWebhookEndpoint.php @@ -73,7 +73,7 @@ class IncomingWebhookEndpoint 'info', sprintf( __('Webhook has been handled by %s', 'woocommerce-paypal-commerce-gateway'), - $handler->eventType() + ($handler->eventTypes())?current($handler->eventTypes()):'' ), [ 'request' => $request, @@ -93,11 +93,10 @@ class IncomingWebhookEndpoint } public function handledEventTypes() : array { - return array_map( - function(RequestHandler $handler) : string { - return $handler->eventType(); - }, - $this->handlers - ); + $eventTypes = []; + foreach ($this->handlers as $handler) { + $eventTypes = array_merge($eventTypes, $handler->eventTypes()); + } + return array_unique($eventTypes); } }