diff --git a/modules/ppcp-api-client/services.php b/modules/ppcp-api-client/services.php index acb879e2b..be80943bf 100644 --- a/modules/ppcp-api-client/services.php +++ b/modules/ppcp-api-client/services.php @@ -12,6 +12,7 @@ namespace WooCommerce\PayPalCommerce\ApiClient; use Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller; use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint; @@ -191,6 +192,13 @@ return array( $subscription_helper ); }, + 'api.endpoint.billing-agreements' => static function ( ContainerInterface $container ): BillingAgreementsEndpoint { + return new BillingAgreementsEndpoint( + $container->get( 'api.host' ), + $container->get( 'api.bearer' ), + $container->get( 'woocommerce.logger.woocommerce' ) + ); + }, 'api.repository.paypal-request-id' => static function( ContainerInterface $container ) : PayPalRequestIdRepository { return new PayPalRequestIdRepository(); }, diff --git a/modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php b/modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php new file mode 100644 index 000000000..9618574b5 --- /dev/null +++ b/modules/ppcp-api-client/src/Endpoint/BillingAgreementsEndpoint.php @@ -0,0 +1,138 @@ +host = $host; + $this->bearer = $bearer; + $this->logger = $logger; + } + + /** + * Creates a billing agreement token. + * + * @param string $description The description. + * @param string $return_url The return URL. + * @param string $cancel_url The cancel URL. + * + * @throws RuntimeException If the request fails. + * @throws PayPalApiException If the request fails. + */ + public function create_token( string $description, string $return_url, string $cancel_url ): stdClass { + $data = array( + 'description' => $description, + 'payer' => array( + 'payment_method' => 'PAYPAL', + ), + 'plan' => array( + 'type' => 'MERCHANT_INITIATED_BILLING', + 'merchant_preferences' => array( + 'return_url' => $return_url, + 'cancel_url' => $cancel_url, + 'skip_shipping_address' => true, + ), + ), + ); + + $bearer = $this->bearer->bearer(); + $url = trailingslashit( $this->host ) . 'v1/billing-agreements/agreement-tokens'; + $args = array( + 'method' => 'POST', + 'headers' => array( + 'Authorization' => 'Bearer ' . $bearer->token(), + 'Content-Type' => 'application/json', + ), + 'body' => wp_json_encode( $data ), + ); + $response = $this->request( $url, $args ); + + if ( is_wp_error( $response ) || ! is_array( $response ) ) { + throw new RuntimeException( 'Not able to create a billing agreement token.' ); + } + + $json = json_decode( $response['body'] ); + $status_code = (int) wp_remote_retrieve_response_code( $response ); + if ( 201 !== $status_code ) { + throw new PayPalApiException( + $json, + $status_code + ); + } + + return $json; + } + + /** + * Checks if reference transactions are enabled in account. + * + * @throws RuntimeException If the request fails (no auth, no connection, etc.). + */ + public function reference_transaction_enabled(): bool { + try { + $this->create_token( + 'Checking if reference transactions are enabled', + 'https://example.com/return', + 'https://example.com/cancel' + ); + + return true; + } catch ( PayPalApiException $exception ) { + return false; + } + } +} diff --git a/modules/ppcp-status-report/src/StatusReportModule.php b/modules/ppcp-status-report/src/StatusReportModule.php index 5b6186ea9..5f5a30935 100644 --- a/modules/ppcp-status-report/src/StatusReportModule.php +++ b/modules/ppcp-status-report/src/StatusReportModule.php @@ -15,6 +15,7 @@ use Interop\Container\ServiceProviderInterface; use Psr\Container\ContainerInterface; use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer; use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer; +use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint; use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException; use WooCommerce\PayPalCommerce\ApiClient\Helper\CurrencySupport; use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies; @@ -68,6 +69,9 @@ class StatusReportModule implements ModuleInterface { $last_webhook_storage = $c->get( 'webhook.last-webhook-storage' ); assert( $last_webhook_storage instanceof WebhookInfoStorage ); + $billing_agreements_endpoint = $c->get( 'api.endpoint.billing-agreements' ); + assert( $billing_agreements_endpoint instanceof BillingAgreementsEndpoint ); + /* @var Renderer $renderer The renderer. */ $renderer = $c->get( 'status-report.renderer' ); @@ -134,6 +138,14 @@ class StatusReportModule implements ModuleInterface { $settings->has( 'logging_enabled' ) && $settings->get( 'logging_enabled' ) ), ), + array( + 'label' => esc_html__( 'Reference Transactions', 'woocommerce-paypal-payments' ), + 'exported_label' => 'Reference Transactions', + 'description' => esc_html__( 'Whether Reference Transactions are enabled for the connected account', 'woocommerce-paypal-payments' ), + 'value' => $this->bool_to_text( + $this->reference_transaction_enabled( $billing_agreements_endpoint ) + ), + ), array( 'label' => esc_html__( 'Used PayPal Checkout plugin', 'woocommerce-paypal-payments' ), 'exported_label' => 'Used PayPal Checkout plugin', @@ -192,6 +204,19 @@ class StatusReportModule implements ModuleInterface { } } + /** + * Checks if reference transactions are enabled in account. + * + * @param BillingAgreementsEndpoint $billing_agreements_endpoint The endpoint. + */ + private function reference_transaction_enabled( BillingAgreementsEndpoint $billing_agreements_endpoint ): bool { + try { + return $billing_agreements_endpoint->reference_transaction_enabled(); + } catch ( RuntimeException $exception ) { + return false; + } + } + /** * Converts the bool value to "Yes" or "No". *