mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-10 15:10:47 +08:00
227 lines
5.4 KiB
PHP
227 lines
5.4 KiB
PHP
<?php
|
|
/**
|
|
* Handles the Webhook CHECKOUT.ORDER.APPROVED
|
|
*
|
|
* @package WooCommerce\PayPalCommerce\Webhooks\Handler
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
|
|
|
|
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
|
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
|
use Psr\Log\LoggerInterface;
|
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOGateway;
|
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
|
|
|
/**
|
|
* Class CheckoutOrderApproved
|
|
*/
|
|
class CheckoutOrderApproved implements RequestHandler {
|
|
|
|
use PrefixTrait;
|
|
|
|
/**
|
|
* The logger.
|
|
*
|
|
* @var LoggerInterface
|
|
*/
|
|
private $logger;
|
|
|
|
/**
|
|
* The order endpoint.
|
|
*
|
|
* @var OrderEndpoint
|
|
*/
|
|
private $order_endpoint;
|
|
|
|
/**
|
|
* CheckoutOrderApproved constructor.
|
|
*
|
|
* @param LoggerInterface $logger The logger.
|
|
* @param string $prefix The prefix.
|
|
* @param OrderEndpoint $order_endpoint The order endpoint.
|
|
*/
|
|
public function __construct( LoggerInterface $logger, string $prefix, OrderEndpoint $order_endpoint ) {
|
|
$this->logger = $logger;
|
|
$this->prefix = $prefix;
|
|
$this->order_endpoint = $order_endpoint;
|
|
}
|
|
|
|
/**
|
|
* The event types a handler handles.
|
|
*
|
|
* @return string[]
|
|
*/
|
|
public function event_types(): array {
|
|
return array(
|
|
'CHECKOUT.ORDER.APPROVED',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Whether a handler is responsible for a given request or not.
|
|
*
|
|
* @param \WP_REST_Request $request The request.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function responsible_for_request( \WP_REST_Request $request ): bool {
|
|
return in_array( $request['event_type'], $this->event_types(), true );
|
|
}
|
|
|
|
/**
|
|
* Responsible for handling the request.
|
|
*
|
|
* @param \WP_REST_Request $request The request.
|
|
*
|
|
* @return \WP_REST_Response
|
|
*/
|
|
public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
|
|
$response = array( 'success' => false );
|
|
$custom_ids = array_filter(
|
|
array_map(
|
|
static function ( array $purchase_unit ): string {
|
|
return isset( $purchase_unit['custom_id'] ) ?
|
|
(string) $purchase_unit['custom_id'] : '';
|
|
},
|
|
isset( $request['resource']['purchase_units'] ) ?
|
|
(array) $request['resource']['purchase_units'] : array()
|
|
),
|
|
static function ( string $order_id ): bool {
|
|
return ! empty( $order_id );
|
|
}
|
|
);
|
|
|
|
if ( empty( $custom_ids ) ) {
|
|
$message = sprintf(
|
|
// translators: %s is the PayPal webhook Id.
|
|
__(
|
|
'No order for webhook event %s was found.',
|
|
'woocommerce-paypal-payments'
|
|
),
|
|
isset( $request['id'] ) ? $request['id'] : ''
|
|
);
|
|
$this->logger->log(
|
|
'warning',
|
|
$message,
|
|
array(
|
|
'request' => $request,
|
|
)
|
|
);
|
|
$response['message'] = $message;
|
|
return rest_ensure_response( $response );
|
|
}
|
|
|
|
try {
|
|
$order = isset( $request['resource']['id'] ) ?
|
|
$this->order_endpoint->order( $request['resource']['id'] ) : null;
|
|
if ( ! $order ) {
|
|
$message = sprintf(
|
|
// translators: %s is the PayPal webhook Id.
|
|
__(
|
|
'No paypal payment for webhook event %s was found.',
|
|
'woocommerce-paypal-payments'
|
|
),
|
|
isset( $request['id'] ) ? $request['id'] : ''
|
|
);
|
|
$this->logger->log(
|
|
'warning',
|
|
$message,
|
|
array(
|
|
'request' => $request,
|
|
)
|
|
);
|
|
$response['message'] = $message;
|
|
return rest_ensure_response( $response );
|
|
}
|
|
|
|
if ( $order->intent() === 'CAPTURE' ) {
|
|
$order = $this->order_endpoint->capture( $order );
|
|
}
|
|
} catch ( RuntimeException $error ) {
|
|
$message = sprintf(
|
|
// translators: %s is the PayPal webhook Id.
|
|
__(
|
|
'Could not capture payment for webhook event %s.',
|
|
'woocommerce-paypal-payments'
|
|
),
|
|
isset( $request['id'] ) ? $request['id'] : ''
|
|
);
|
|
$this->logger->log(
|
|
'warning',
|
|
$message,
|
|
array(
|
|
'request' => $request,
|
|
)
|
|
);
|
|
$response['message'] = $message;
|
|
return rest_ensure_response( $response );
|
|
}
|
|
|
|
$wc_order_ids = array_map(
|
|
array(
|
|
$this,
|
|
'sanitize_custom_id',
|
|
),
|
|
$custom_ids
|
|
);
|
|
$args = array(
|
|
'post__in' => $wc_order_ids,
|
|
'limit' => -1,
|
|
);
|
|
$wc_orders = wc_get_orders( $args );
|
|
if ( ! $wc_orders ) {
|
|
$message = sprintf(
|
|
// translators: %s is the PayPal order Id.
|
|
__( 'Order for PayPal order %s not found.', 'woocommerce-paypal-payments' ),
|
|
isset( $request['resource']['id'] ) ? $request['resource']['id'] : ''
|
|
);
|
|
$this->logger->log(
|
|
'warning',
|
|
$message,
|
|
array(
|
|
'request' => $request,
|
|
)
|
|
);
|
|
$response['message'] = $message;
|
|
return rest_ensure_response( $response );
|
|
}
|
|
|
|
foreach ( $wc_orders as $wc_order ) {
|
|
if ( PayUponInvoiceGateway::ID === $wc_order->get_payment_method() || OXXOGateway::ID === $wc_order->get_payment_method() ) {
|
|
continue;
|
|
}
|
|
|
|
if ( ! in_array( $wc_order->get_status(), array( 'pending', 'on-hold' ), true ) ) {
|
|
continue;
|
|
}
|
|
if ( $order->intent() === 'CAPTURE' ) {
|
|
$wc_order->payment_complete();
|
|
} else {
|
|
$wc_order->update_status(
|
|
'on-hold',
|
|
__( 'Payment can be captured.', 'woocommerce-paypal-payments' )
|
|
);
|
|
}
|
|
$this->logger->log(
|
|
'info',
|
|
sprintf(
|
|
// translators: %s is the order ID.
|
|
__(
|
|
'Order %s has been updated through PayPal',
|
|
'woocommerce-paypal-payments'
|
|
),
|
|
(string) $wc_order->get_id()
|
|
),
|
|
array(
|
|
'request' => $request,
|
|
'order' => $wc_order,
|
|
)
|
|
);
|
|
}
|
|
$response['success'] = true;
|
|
return rest_ensure_response( $response );
|
|
}
|
|
}
|