File "ConnectManualRestEndpoint.php"

Full Path: /home/siazco/grocery.siazco.se/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-settings/src/Endpoint/ConnectManualRestEndpoint.php
File size: 5.22 KB
MIME-type: text/x-php
Charset: utf-8

<?php
/**
 * REST controller for connection via manual credentials input.
 *
 * @package WooCommerce\PayPalCommerce\Settings\Endpoint
 */

declare( strict_types = 1 );

namespace WooCommerce\PayPalCommerce\Settings\Endpoint;

use Exception;
use Psr\Log\LoggerInterface;
use RuntimeException;
use stdClass;
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\Orders;
use WooCommerce\PayPalCommerce\ApiClient\Helper\InMemoryCache;
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WP_REST_Server;
use WP_REST_Response;
use WP_REST_Request;

/**
 * REST controller for connection via manual credentials input.
 */
class ConnectManualRestEndpoint extends RestEndpoint {

	/**
	 * The API host for the live mode.
	 *
	 * @var string
	 */
	private string $live_host;

	/**
	 * The API host for the sandbox mode.
	 *
	 * @var string
	 */
	private string $sandbox_host;

	/**
	 * The logger.
	 *
	 * @var LoggerInterface
	 */
	private $logger;

	/**
	 * The base path for this REST controller.
	 *
	 * @var string
	 */
	protected $rest_base = 'connect_manual';

	/**
	 * Field mapping for request.
	 *
	 * @var array
	 */
	private array $field_map = array(
		'client_id'     => array(
			'js_name'  => 'clientId',
			'sanitize' => 'sanitize_text_field',
		),
		'client_secret' => array(
			'js_name'  => 'clientSecret',
			'sanitize' => 'sanitize_text_field',
		),
		'use_sandbox'   => array(
			'js_name'  => 'useSandbox',
			'sanitize' => 'to_boolean',
		),
	);

	/**
	 * ConnectManualRestEndpoint constructor.
	 *
	 * @param string          $live_host The API host for the live mode.
	 * @param string          $sandbox_host The API host for the sandbox mode.
	 * @param LoggerInterface $logger The logger.
	 */
	public function __construct(
		string $live_host,
		string $sandbox_host,
		LoggerInterface $logger
	) {

		$this->live_host    = $live_host;
		$this->sandbox_host = $sandbox_host;
		$this->logger       = $logger;
	}

	/**
	 * Configure REST API routes.
	 */
	public function register_routes() {
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base,
			array(
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'connect_manual' ),
					'permission_callback' => array( $this, 'check_permission' ),
				),
			)
		);
	}

	/**
	 * Retrieves merchantId and email.
	 *
	 * @param WP_REST_Request $request Full data about the request.
	 */
	public function connect_manual( WP_REST_Request $request ) : WP_REST_Response {
		$data = $this->sanitize_for_wordpress(
			$request->get_params(),
			$this->field_map
		);

		$client_id     = $data['client_id'] ?? '';
		$client_secret = $data['client_secret'] ?? '';
		$use_sandbox   = (bool) ( $data['use_sandbox'] ?? false );

		if ( empty( $client_id ) || empty( $client_secret ) ) {
			return rest_ensure_response(
				array(
					'success' => false,
					'message' => 'No client ID or secret provided.',
				)
			);
		}

		try {
			$payee = $this->request_payee( $client_id, $client_secret, $use_sandbox );
		} catch ( Exception $exception ) {
			return rest_ensure_response(
				array(
					'success' => false,
					'message' => $exception->getMessage(),
				)
			);

		}

		$result = array(
			'merchantId' => $payee->merchant_id,
			'email'      => $payee->email_address,
			'success'    => true,
		);

		return rest_ensure_response( $result );
	}

	/**
	 * Retrieves the payee object with the merchant data
	 * by creating a minimal PayPal order.
	 *
	 * @param string $client_id The client ID.
	 * @param string $client_secret The client secret.
	 * @param bool   $use_sandbox Whether to use the sandbox mode.
	 * @return stdClass The payee object.
	 * @throws Exception When failed to retrieve payee.
	 *
	 * phpcs:disable Squiz.Commenting
	 * phpcs:disable Generic.Commenting
	 */
	private function request_payee(
		string $client_id,
		string $client_secret,
		bool $use_sandbox
	) : stdClass {

		$host = $use_sandbox ? $this->sandbox_host : $this->live_host;

		$empty_settings = new class() implements ContainerInterface
		{
			public function get( string $id ) {
				throw new NotFoundException();
			}

			public function has( string $id ) {
				return false;
			}
		};

		$bearer = new PayPalBearer(
			new InMemoryCache(),
			$host,
			$client_id,
			$client_secret,
			$this->logger,
			$empty_settings
		);

		$orders = new Orders(
			$host,
			$bearer,
			$this->logger
		);

		$request_body = array(
			'intent'         => 'CAPTURE',
			'purchase_units' => array(
				array(
					'amount' => array(
						'currency_code' => 'USD',
						'value'         => 1.0,
					),
				),
			),
		);

		$response = $orders->create( $request_body );
		$body     = json_decode( $response['body'] );

		$order_id = $body->id;

		$order_response = $orders->order( $order_id );
		$order_body     = json_decode( $order_response['body'] );

		$pu    = $order_body->purchase_units[0];
		$payee = $pu->payee;
		if ( ! is_object( $payee ) ) {
			throw new RuntimeException( 'Payee not found.' );
		}
		if ( ! isset( $payee->merchant_id ) || ! isset( $payee->email_address ) ) {
			throw new RuntimeException( 'Payee info not found.' );
		}

		return $payee;
	}
}