esponse( $token_value ); } return $tokens; } /** * Returns the payment tokens for the given guest customer id. * * @param string $customer_id The guest customer id. * * @return PaymentToken[] * @throws RuntimeException If the request fails. */ public function for_guest( string $customer_id ): array { $bearer = $this->bearer->bearer(); $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/?customer_id=' . $customer_id; $args = array( 'method' => 'GET', 'headers' => array( 'Authorization' => 'Bearer ' . $bearer->token(), 'Content-Type' => 'application/json', ), ); $response = $this->request( $url, $args ); if ( $response instanceof WP_Error ) { $error = new RuntimeException( __( 'Could not fetch payment token for guest customer id.', 'woocommerce-paypal-payments' ) ); $this->logger->log( 'warning', $error->getMessage(), array( 'args' => $args, 'response' => $response, ) ); throw $error; } $json = json_decode( $response['body'] ); $status_code = (int) wp_remote_retrieve_response_code( $response ); if ( 200 !== $status_code ) { $error = new PayPalApiException( $json, $status_code ); $this->logger->log( 'warning', $error->getMessage(), array( 'args' => $args, 'response' => $response, ) ); throw $error; } $tokens = array(); foreach ( $json->payment_tokens as $token_value ) { $tokens[] = $this->factory->from_paypal_response( $token_value ); } return $tokens; } /** * Deletes a payment token. * * @param PaymentToken $token The token to delete. * * @return bool * @throws RuntimeException If the request fails. */ public function delete_token( PaymentToken $token ): bool { $bearer = $this->bearer->bearer(); $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/' . $token->id(); $args = array( 'method' => 'DELETE', 'headers' => array( 'Authorization' => 'Bearer ' . $bearer->token(), 'Content-Type' => 'application/json', ), ); $response = $this->request( $url, $args ); if ( is_wp_error( $response ) ) { $error = new RuntimeException( __( 'Could not delete payment token.', 'woocommerce-paypal-payments' ) ); $this->logger->log( 'warning', $error->getMessage(), array( 'args' => $args, 'response' => $response, ) ); throw $error; } return wp_remote_retrieve_response_code( $response ) === 204; } /** * Deletes payment token by the given id. * * @param string $token_id Token id. * @return bool * * @throws RuntimeException If something goes wrong while deleting the token. */ public function delete_token_by_id( string $token_id ): bool { $bearer = $this->bearer->bearer(); $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens/' . $token_id; $args = array( 'method' => 'DELETE', 'headers' => array( 'Authorization' => 'Bearer ' . $bearer->token(), 'Content-Type' => 'application/json', ), ); $response = $this->request( $url, $args ); if ( is_wp_error( $response ) ) { $error = new RuntimeException( __( 'Could not delete payment token.', 'woocommerce-paypal-payments' ) ); $this->logger->warning( $error->getMessage() ); throw $error; } return wp_remote_retrieve_response_code( $response ) === 204; } /** * Starts the process of PayPal account vaulting (without payment), returns the links for further actions. * * @param int $user_id The WP user id. * @param string $return_url The URL to which the customer is redirected after finishing the approval. * @param string $cancel_url The URL to which the customer is redirected if cancelled the operation. * * @return PaymentTokenActionLinks * @throws RuntimeException If the request fails. * @throws PayPalApiException If the request fails. */ public function start_paypal_token_creation( int $user_id, string $return_url, string $cancel_url ): PaymentTokenActionLinks { $bearer = $this->bearer->bearer(); $url = trailingslashit( $this->host ) . 'v2/vault/payment-tokens'; $customer_id = $this->customer_repository->customer_id_for_user( ( $user_id ) ); $data = array( 'customer_id' => $customer_id, 'source' => array( 'paypal' => array( 'usage_type' => 'MERCHANT', ), ), 'application_context' => array( 'return_url' => $return_url, 'cancel_url' => $cancel_url, // TODO: can use vault_on_approval to avoid /confirm-payment-token, but currently it's not working. ), ); $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( 'Failed to create payment token.' ); } $json = json_decode( $response['body'] ); $status_code = (int) wp_remote_retrieve_response_code( $response ); if ( 200 !== $status_code ) { throw new PayPalApiException( $json, $status_code ); } $status = $json->status; if ( 'CUSTOMER_ACTION_REQUIRED' !== $status ) { throw new RuntimeException( 'Unexpected payment token creation status. ' . $status ); } $links = $this->payment_token_action_links_factory->from_paypal_response( $json ); return $links; } /** * Finishes the process of PayPal account vaulting. * * @param string $approval_token The id of the approval token approved by the customer. * @param int $user_id The WP user id. * * @return string * @throws RuntimeException If the request fails. * @throws PayPalApiException If the request fails. * @throws AlreadyVaultedException When new token was not created (for example, already vaulted with this merchant). */ public function create_from_approval_token( string $approval_token, int $user_id ): string { $bearer = $this->bearer->bearer(); $url = trailingslashit( $this->host ) . 'v2/vault/approval-tokens/' . $approval_token . '/confirm-payment-token'; $args = array( 'method' => 'POST', 'headers' => array( 'Authorization' => 'Bearer ' . $bearer->token(), 'Content-Type' => 'application/json', ), ); $response = $this->request( $url, $args ); if ( is_wp_error( $response ) || ! is_array( $response ) ) { throw new RuntimeException( 'Failed to create payment token from approval token.' ); } $json = json_decode( $response['body'] ); $status_code = (int) wp_remote_retrieve_response_code( $response ); if ( 200 === $status_code ) { throw new AlreadyVaultedException( 'Already vaulted.' ); } if ( 201 !== $status_code ) { throw new PayPalApiException( $json, $status_code ); } return $json->id; } }
Fatal error: Uncaught Error: Class "WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokenEndpoint" not found in /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-api-client/services.php:148 Stack trace: #0 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Container/ReadOnlyContainer.php(71): WooCommerce\PayPalCommerce\ApiClient\ApiModule::WooCommerce\PayPalCommerce\ApiClient\{closure}(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #1 /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-vaulting/services.php(23): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer->get('api.endpoint.pa...') #2 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Container/ReadOnlyContainer.php(71): WooCommerce\PayPalCommerce\Vaulting\VaultingModule::WooCommerce\PayPalCommerce\Vaulting\{closure}(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #3 /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-wc-subscriptions/services.php(27): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer->get('vaulting.reposi...') #4 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Container/ReadOnlyContainer.php(71): WooCommerce\PayPalCommerce\WcSubscriptions\WcSubscriptionsModule::WooCommerce\PayPalCommerce\WcSubscriptions\{closure}(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #5 /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-compat/services.php(30): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer->get('wc-subscription...') #6 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Container/ReadOnlyContainer.php(71): WooCommerce\PayPalCommerce\Compat\CompatModule::WooCommerce\PayPalCommerce\Compat\{closure}(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #7 /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-compat/src/CompatModule.php(93): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer->get('compat.ppec.sub...') #8 /htdocs/wp-content/plugins/woocommerce-paypal-payments/modules/ppcp-compat/src/CompatModule.php(54): WooCommerce\PayPalCommerce\Compat\CompatModule->initialize_ppec_compat_layer(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #9 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Package.php(530): WooCommerce\PayPalCommerce\Compat\CompatModule->run(Object(WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Container\ReadOnlyContainer)) #10 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Package.php(405): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Package->doExecute() #11 /htdocs/wp-content/plugins/woocommerce-paypal-payments/bootstrap.php(40): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Package->boot() #12 /htdocs/wp-content/plugins/woocommerce-paypal-payments/woocommerce-paypal-payments.php(77): {closure}('/htdocs/wp-cont...') #13 /htdocs/wp-content/plugins/woocommerce-paypal-payments/woocommerce-paypal-payments.php(92): WooCommerce\PayPalCommerce\init() #14 /htdocs/wp-includes/class-wp-hook.php(324): WooCommerce\PayPalCommerce\{closure}('') #15 /htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #16 /htdocs/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #17 /htdocs/wp-settings.php(559): do_action('plugins_loaded') #18 /htdocs/wp-config.php(86): require_once('/htdocs/wp-sett...') #19 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #20 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #21 /htdocs/index.php(17): require('/htdocs/wp-blog...') #22 {main} Next Exception: Can't obtain the container instance at this point of application. in /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Package.php:701 Stack trace: #0 /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Package.php(639): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Package->assertStatus(4, 'obtain the cont...', '>=') #1 /htdocs/wp-content/plugins/woocommerce-paypal-payments/bootstrap.php(42): WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Package->container() #2 /htdocs/wp-content/plugins/woocommerce-paypal-payments/woocommerce-paypal-payments.php(77): {closure}('/htdocs/wp-cont...') #3 /htdocs/wp-content/plugins/woocommerce-paypal-payments/woocommerce-paypal-payments.php(92): WooCommerce\PayPalCommerce\init() #4 /htdocs/wp-includes/class-wp-hook.php(324): WooCommerce\PayPalCommerce\{closure}('') #5 /htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #6 /htdocs/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #7 /htdocs/wp-settings.php(559): do_action('plugins_loaded') #8 /htdocs/wp-config.php(86): require_once('/htdocs/wp-sett...') #9 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #10 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #11 /htdocs/index.php(17): require('/htdocs/wp-blog...') #12 {main} thrown in /htdocs/wp-content/plugins/woocommerce-paypal-payments/lib/packages/Inpsyde/Modularity/Package.php on line 701