mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 12:25:15 +08:00
Merge branch 'trunk' into modularity-module-migration
# Conflicts: # modules/ppcp-wc-gateway/src/WCGatewayModule.php
This commit is contained in:
commit
161e933d39
96 changed files with 6599 additions and 223 deletions
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentTokensEndpoint;
|
||||
|
@ -1408,32 +1409,32 @@ return array(
|
|||
'BE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'CAD' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'BG' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'CY' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'CZ' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'CZK' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'DE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'DK' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'DKK' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'EE' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1443,32 +1444,32 @@ return array(
|
|||
'ES' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'FI' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'FR' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'GB' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'GBP', 'USD' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'GR' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'HU' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'HUF' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'IE' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1478,7 +1479,7 @@ return array(
|
|||
'IT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'US' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1489,7 +1490,7 @@ return array(
|
|||
'CA' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'CAD' ),
|
||||
'amex' => array( 'CAD', 'USD' ),
|
||||
'jcb' => array( 'CAD' ),
|
||||
),
|
||||
'LI' => array(
|
||||
|
@ -1500,22 +1501,22 @@ return array(
|
|||
'LT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'LU' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'LV' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'MT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'MX' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1525,7 +1526,7 @@ return array(
|
|||
'NL' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'NO' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1535,32 +1536,32 @@ return array(
|
|||
'PL' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'GBP', 'PLN' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'PT' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD', 'CAD', 'GBP' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'RO' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'USD' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'SE' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'SEK' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'SI' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'SK' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array( 'EUR', 'GBP' ),
|
||||
'amex' => array(),
|
||||
),
|
||||
'JP' => array(
|
||||
'mastercard' => array(),
|
||||
|
@ -1633,4 +1634,11 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'api.sdk-client-token' => static function( ContainerInterface $container ): SdkClientToken {
|
||||
return new SdkClientToken(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
109
modules/ppcp-api-client/src/Authentication/SdkClientToken.php
Normal file
109
modules/ppcp-api-client/src/Authentication/SdkClientToken.php
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
/**
|
||||
* Generates user ID token for payer.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Authentication
|
||||
*/
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
* Class SdkClientToken
|
||||
*/
|
||||
class SdkClientToken {
|
||||
|
||||
use RequestTrait;
|
||||
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* SdkClientToken constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `sdk_client_token` which uniquely identifies the payer.
|
||||
*
|
||||
* @param string $target_customer_id Vaulted customer id.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws PayPalApiException If the request fails.
|
||||
* @throws RuntimeException If something unexpected happens.
|
||||
*/
|
||||
public function sdk_client_token( string $target_customer_id = '' ): string {
|
||||
$bearer = $this->bearer->bearer();
|
||||
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$domain = wp_unslash( $_SERVER['HTTP_HOST'] ?? '' );
|
||||
|
||||
$url = trailingslashit( $this->host ) . 'v1/oauth2/token?grant_type=client_credentials&response_type=client_token&intent=sdk_init&domains[]=*.' . $domain;
|
||||
|
||||
if ( $target_customer_id ) {
|
||||
$url = add_query_arg(
|
||||
array(
|
||||
'target_customer_id' => $target_customer_id,
|
||||
),
|
||||
$url
|
||||
);
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
),
|
||||
);
|
||||
|
||||
$response = $this->request( $url, $args );
|
||||
if ( $response instanceof WP_Error ) {
|
||||
throw new RuntimeException( $response->get_error_message() );
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'] );
|
||||
$status_code = (int) wp_remote_retrieve_response_code( $response );
|
||||
if ( 200 !== $status_code ) {
|
||||
throw new PayPalApiException( $json, $status_code );
|
||||
}
|
||||
|
||||
return $json->access_token;
|
||||
}
|
||||
}
|
|
@ -115,7 +115,7 @@ class PaymentMethodTokensEndpoint {
|
|||
* @throws RuntimeException When something when wrong with the request.
|
||||
* @throws PayPalApiException When something when wrong setting up the token.
|
||||
*/
|
||||
public function payment_tokens( PaymentSource $payment_source ): stdClass {
|
||||
public function create_payment_token( PaymentSource $payment_source ): stdClass {
|
||||
$data = array(
|
||||
'payment_source' => array(
|
||||
$payment_source->name() => $payment_source->properties(),
|
||||
|
|
|
@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Exception;
|
||||
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class PayPalApiException
|
||||
*/
|
||||
|
@ -17,7 +19,7 @@ class PayPalApiException extends RuntimeException {
|
|||
/**
|
||||
* The JSON response object of PayPal.
|
||||
*
|
||||
* @var \stdClass
|
||||
* @var stdClass
|
||||
*/
|
||||
private $response;
|
||||
|
||||
|
@ -31,10 +33,10 @@ class PayPalApiException extends RuntimeException {
|
|||
/**
|
||||
* PayPalApiException constructor.
|
||||
*
|
||||
* @param \stdClass|null $response The JSON object.
|
||||
* @param int $status_code The HTTP status code.
|
||||
* @param stdClass|null $response The JSON object.
|
||||
* @param int $status_code The HTTP status code.
|
||||
*/
|
||||
public function __construct( \stdClass $response = null, int $status_code = 0 ) {
|
||||
public function __construct( stdClass $response = null, int $status_code = 0 ) {
|
||||
if ( is_null( $response ) ) {
|
||||
$response = new \stdClass();
|
||||
}
|
||||
|
@ -65,7 +67,7 @@ class PayPalApiException extends RuntimeException {
|
|||
*/
|
||||
$this->response = $response;
|
||||
$this->status_code = $status_code;
|
||||
$message = $response->message;
|
||||
$message = $this->get_customer_friendly_message( $response );
|
||||
if ( $response->name ) {
|
||||
$message = '[' . $response->name . '] ' . $message;
|
||||
}
|
||||
|
@ -141,4 +143,40 @@ class PayPalApiException extends RuntimeException {
|
|||
|
||||
return $details;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a friendly message if the error detail is known.
|
||||
*
|
||||
* @param stdClass $json The response.
|
||||
* @return string
|
||||
*/
|
||||
public function get_customer_friendly_message( stdClass $json ): string {
|
||||
if ( empty( $json->details ) ) {
|
||||
return $json->message;
|
||||
}
|
||||
$improved_keys_messages = array(
|
||||
'PAYMENT_DENIED' => __( 'PayPal rejected the payment. Please reach out to the PayPal support for more information.', 'woocommerce-paypal-payments' ),
|
||||
'TRANSACTION_REFUSED' => __( 'The transaction has been refused by the payment processor. Please reach out to the PayPal support for more information.', 'woocommerce-paypal-payments' ),
|
||||
'DUPLICATE_INVOICE_ID' => __( 'The transaction has been refused because the Invoice ID already exists. Please create a new order or reach out to the store owner.', 'woocommerce-paypal-payments' ),
|
||||
'PAYER_CANNOT_PAY' => __( 'There was a problem processing this transaction. Please reach out to the store owner.', 'woocommerce-paypal-payments' ),
|
||||
'PAYEE_ACCOUNT_RESTRICTED' => __( 'There was a problem processing this transaction. Please reach out to the store owner.', 'woocommerce-paypal-payments' ),
|
||||
'AGREEMENT_ALREADY_CANCELLED' => __( 'The requested agreement is already canceled. Please reach out to the PayPal support for more information.', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
$improved_errors = array_filter(
|
||||
array_keys( $improved_keys_messages ),
|
||||
function ( $key ) use ( $json ): bool {
|
||||
foreach ( $json->details as $detail ) {
|
||||
if ( isset( $detail->issue ) && $detail->issue === $key ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
if ( $improved_errors ) {
|
||||
$improved_errors = array_values( $improved_errors );
|
||||
return $improved_keys_messages[ $improved_errors[0] ];
|
||||
}
|
||||
return $json->message;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ class ApplicationContextRepository {
|
|||
$payment_preference = $this->settings->has( 'payee_preferred' ) && $this->settings->get( 'payee_preferred' ) ?
|
||||
ApplicationContext::PAYMENT_METHOD_IMMEDIATE_PAYMENT_REQUIRED : ApplicationContext::PAYMENT_METHOD_UNRESTRICTED;
|
||||
$context = new ApplicationContext(
|
||||
network_home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) ),
|
||||
home_url( \WC_AJAX::get_endpoint( ReturnUrlEndpoint::ENDPOINT ) ),
|
||||
(string) wc_get_checkout_url(),
|
||||
(string) $brand_name,
|
||||
$locale,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue