Retrieve merchant data by creating order

This commit is contained in:
Alex P. 2024-11-06 09:15:53 +02:00
parent 1659d30ded
commit a31ae1da77
No known key found for this signature in database
GPG key ID: 54487A734A204D71
4 changed files with 221 additions and 5 deletions

View file

@ -0,0 +1,66 @@
<?php
/**
* An in-memory version of Cache.
*
* @package WooCommerce\PayPalCommerce\ApiClient\Helper
*/
declare( strict_types=1 );
namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
/**
* An in-memory version of Cache. The data is kept only within the class instance.
*/
class InMemoryCache extends Cache {
/**
* The in-memory storage.
*
* @var array<string, mixed>
*/
private array $data = array();
/**
* InMemoryCache constructor
*/
public function __construct() {
parent::__construct( '' );
}
/**
* Gets a value.
*
* @param string $key The key under which the value is stored.
*
* @return mixed
*/
public function get( string $key ) {
if ( ! array_key_exists( $key, $this->data ) ) {
return false;
}
return $this->data[ $key ];
}
/**
* Deletes a cache.
*
* @param string $key The key.
*/
public function delete( string $key ): void {
unset( $this->data[ $key ] );
}
/**
* Caches a value.
*
* @param string $key The key under which the value should be cached.
* @param mixed $value The value to cache.
* @param int $expiration Unused.
*
* @return bool
*/
public function set( string $key, $value, int $expiration = 0 ): bool {
$this->data[ $key ] = $value;
return true;
}
}

View file

@ -100,6 +100,8 @@ const WelcomeForm = ( { setCompleted } ) => {
throw new Error( 'Request failed.' ); throw new Error( 'Request failed.' );
} }
console.log(`Merchant ID: ${res.merchantId}, email: ${res.email}`);
setCompleted( true ); setCompleted( true );
} catch ( exc ) { } catch ( exc ) {
console.error( exc ); console.error( exc );

View file

@ -47,7 +47,11 @@ return array(
return new OnboardingRestEndpoint( $container->get( 'settings.data.onboarding' ) ); return new OnboardingRestEndpoint( $container->get( 'settings.data.onboarding' ) );
}, },
'settings.rest.connect_manual' => static function ( ContainerInterface $container ) : ConnectManualRestEndpoint { 'settings.rest.connect_manual' => static function ( ContainerInterface $container ) : ConnectManualRestEndpoint {
return new ConnectManualRestEndpoint(); return new ConnectManualRestEndpoint(
$container->get( 'api.paypal-host-production' ),
$container->get( 'api.paypal-host-sandbox' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
}, },
'settings.casual-selling.supported-countries' => static function ( ContainerInterface $container ) : array { 'settings.casual-selling.supported-countries' => static function ( ContainerInterface $container ) : array {
return array( return array(

View file

@ -9,6 +9,15 @@ declare( strict_types = 1 );
namespace WooCommerce\PayPalCommerce\Settings\Endpoint; 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_Server;
use WP_REST_Response; use WP_REST_Response;
use WP_REST_Request; use WP_REST_Request;
@ -17,6 +26,28 @@ use WP_REST_Request;
* REST controller for connection via manual credentials input. * REST controller for connection via manual credentials input.
*/ */
class ConnectManualRestEndpoint extends RestEndpoint { 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. * The base path for this REST controller.
* *
@ -44,6 +75,24 @@ class ConnectManualRestEndpoint extends RestEndpoint {
), ),
); );
/**
* 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. * Configure REST API routes.
*/ */
@ -72,21 +121,116 @@ class ConnectManualRestEndpoint extends RestEndpoint {
$this->field_map $this->field_map
); );
if ( ! isset( $data['client_id'] ) || empty( $data['client_id'] ) $client_id = $data['client_id'] ?? '';
|| ! isset( $data['client_secret'] ) || empty( $data['client_secret'] ) ) { $client_secret = $data['client_secret'] ?? '';
$use_sandbox = (bool) ( $data['use_sandbox'] ?? false );
if ( empty( $client_id ) || empty( $client_secret ) ) {
return rest_ensure_response( return rest_ensure_response(
array( array(
'success' => false, '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( $result = array(
'merchantId' => 'bt_us@woocommerce.com', 'merchantId' => $payee->merchant_id,
'email' => 'AT45V2DGMKLRY', 'email' => $payee->email_address,
'success' => true, 'success' => true,
); );
return rest_ensure_response( $result ); 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;
}
} }