mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 09:08:09 +08:00
🔀 Merge branch 'trunk'
# Conflicts: # modules/ppcp-applepay/services.php # modules/ppcp-googlepay/services.php
This commit is contained in:
commit
43a441d7a1
55 changed files with 1481 additions and 501 deletions
1
.megaignore
Normal file
1
.megaignore
Normal file
|
@ -0,0 +1 @@
|
|||
-s:*
|
|
@ -1,6 +1,23 @@
|
|||
*** Changelog ***
|
||||
|
||||
= 2.8.2 - xxxx-xx-xx =
|
||||
= 2.8.3 - 2024-08-12 =
|
||||
* Fix - Google Pay: Prevent field validation from being triggered on checkout page load #2474
|
||||
* Fix - Do not add tax info into order meta during order creation #2471
|
||||
* Fix - PayPal declares subscription support when for Subscription mode is set Disable PayPal for subscription #2425
|
||||
* Fix - PayPal js files loaded on non PayPal pages #2411
|
||||
* Fix - Google Pay: Fix the incorrect popup triggering #2414
|
||||
* Fix - Add tax configurator when programmatically creating WC orders #2431
|
||||
* Fix - Shipping callback compatibility with WC Name Your Price plugin #2402
|
||||
* Fix - Uncaught Error: Cannot use object of type ...\Settings as array in .../AbstractPaymentMethodType.php (3253) #2334
|
||||
* Fix - Prevent displaying smart button multiple times on variable product page #2420
|
||||
* Fix - Prevent enabling Standard Card Button when ACDC is enabled #2404
|
||||
* Fix - Use client credentials for user tokens #2491
|
||||
* Fix - Apple Pay: Fix the shipping callback #2492
|
||||
* Enhancement - Separate Google Pay button for Classic Checkout #2430
|
||||
* Enhancement - Add Apple Pay and Google Pay support for China, simplify country-currency matrix #2468
|
||||
* Enhancement - Add AMEX support for Advanced Card Processing in China #2469
|
||||
|
||||
= 2.8.2 - 2024-07-22 =
|
||||
* Fix - Sold individually checkbox automatically disabled after adding product to the cart more than once #2415
|
||||
* Fix - All products "Sold individually" when PayPal Subscriptions selected as Subscriptions Mode #2400
|
||||
* Fix - W3 Total Cache: Remove type from file parameter as sometimes null gets passed causing errors #2403
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\ClientCredentials;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentMethodTokensEndpoint;
|
||||
|
@ -705,6 +706,7 @@ return array(
|
|||
'CN' => array(
|
||||
'mastercard' => array(),
|
||||
'visa' => array(),
|
||||
'amex' => array(),
|
||||
),
|
||||
'CY' => $mastercard_visa_amex,
|
||||
'CZ' => $mastercard_visa_amex,
|
||||
|
@ -811,18 +813,27 @@ return array(
|
|||
return new PurchaseUnitSanitizer( $behavior, $line_name );
|
||||
}
|
||||
),
|
||||
'api.client-credentials' => static function( ContainerInterface $container ): ClientCredentials {
|
||||
return new ClientCredentials(
|
||||
$container->get( 'wcgateway.settings' )
|
||||
);
|
||||
},
|
||||
'api.client-credentials-cache' => static function( ContainerInterface $container ): Cache {
|
||||
return new Cache( 'ppcp-client-credentials-cache' );
|
||||
},
|
||||
'api.user-id-token' => static function( ContainerInterface $container ): UserIdToken {
|
||||
return new UserIdToken(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
$container->get( 'woocommerce.logger.woocommerce' ),
|
||||
$container->get( 'api.client-credentials' )
|
||||
);
|
||||
},
|
||||
'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' )
|
||||
$container->get( 'woocommerce.logger.woocommerce' ),
|
||||
$container->get( 'api.client-credentials' ),
|
||||
$container->get( 'api.client-credentials-cache' )
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -10,6 +10,8 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\ApiClient;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* The client credentials.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Authentication
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Authentication;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
|
||||
/**
|
||||
* Class ClientCredentials
|
||||
*/
|
||||
class ClientCredentials {
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* ClientCredentials constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
*/
|
||||
public function __construct( Settings $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns encoded client credentials.
|
||||
*
|
||||
* @return string
|
||||
* @throws NotFoundException If setting does not found.
|
||||
*/
|
||||
public function credentials(): string {
|
||||
$client_id = $this->settings->has( 'client_id' ) ? $this->settings->get( 'client_id' ) : '';
|
||||
$client_secret = $this->settings->has( 'client_secret' ) ? $this->settings->get( 'client_secret' ) : '';
|
||||
|
||||
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
|
||||
return 'Basic ' . base64_encode( $client_id . ':' . $client_secret );
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ use Psr\Log\LoggerInterface;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\RequestTrait;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WP_Error;
|
||||
|
||||
/**
|
||||
|
@ -20,6 +21,8 @@ class SdkClientToken {
|
|||
|
||||
use RequestTrait;
|
||||
|
||||
const CACHE_KEY = 'sdk-client-token-key';
|
||||
|
||||
/**
|
||||
* The host.
|
||||
*
|
||||
|
@ -27,13 +30,6 @@ class SdkClientToken {
|
|||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
|
@ -41,35 +37,52 @@ class SdkClientToken {
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* The client credentials.
|
||||
*
|
||||
* @var ClientCredentials
|
||||
*/
|
||||
private $client_credentials;
|
||||
|
||||
/**
|
||||
* The cache.
|
||||
*
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* SdkClientToken constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param string $host The host.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param ClientCredentials $client_credentials The client credentials.
|
||||
* @param Cache $cache The cache.
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
ClientCredentials $client_credentials,
|
||||
Cache $cache
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
$this->host = $host;
|
||||
$this->logger = $logger;
|
||||
$this->client_credentials = $client_credentials;
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `sdk_client_token` which uniquely identifies the payer.
|
||||
*
|
||||
* @param string $target_customer_id Vaulted customer id.
|
||||
* Returns the client token for SDK `data-sdk-client-token`.
|
||||
*
|
||||
* @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();
|
||||
public function sdk_client_token(): string {
|
||||
if ( $this->cache->has( self::CACHE_KEY ) ) {
|
||||
return $this->cache->get( self::CACHE_KEY );
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$domain = wp_unslash( $_SERVER['HTTP_HOST'] ?? '' );
|
||||
|
@ -77,19 +90,10 @@ class SdkClientToken {
|
|||
|
||||
$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(),
|
||||
'Authorization' => $this->client_credentials->credentials(),
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
),
|
||||
);
|
||||
|
@ -105,6 +109,11 @@ class SdkClientToken {
|
|||
throw new PayPalApiException( $json, $status_code );
|
||||
}
|
||||
|
||||
return $json->access_token;
|
||||
$access_token = $json->access_token;
|
||||
$expires_in = (int) $json->expires_in;
|
||||
|
||||
$this->cache->set( self::CACHE_KEY, $access_token, $expires_in );
|
||||
|
||||
return $access_token;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,6 @@ class UserIdToken {
|
|||
*/
|
||||
private $host;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
|
@ -41,21 +34,28 @@ class UserIdToken {
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* The client credentials.
|
||||
*
|
||||
* @var ClientCredentials
|
||||
*/
|
||||
private $client_credentials;
|
||||
|
||||
/**
|
||||
* UserIdToken constructor.
|
||||
*
|
||||
* @param string $host The host.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param string $host The host.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param ClientCredentials $client_credentials The client credentials.
|
||||
*/
|
||||
public function __construct(
|
||||
string $host,
|
||||
Bearer $bearer,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
ClientCredentials $client_credentials
|
||||
) {
|
||||
$this->host = $host;
|
||||
$this->bearer = $bearer;
|
||||
$this->logger = $logger;
|
||||
$this->host = $host;
|
||||
$this->logger = $logger;
|
||||
$this->client_credentials = $client_credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,8 +69,6 @@ class UserIdToken {
|
|||
* @throws RuntimeException If something unexpected happens.
|
||||
*/
|
||||
public function id_token( string $target_customer_id = '' ): string {
|
||||
$bearer = $this->bearer->bearer();
|
||||
|
||||
$url = trailingslashit( $this->host ) . 'v1/oauth2/token?grant_type=client_credentials&response_type=id_token';
|
||||
if ( $target_customer_id ) {
|
||||
$url = add_query_arg(
|
||||
|
@ -84,7 +82,7 @@ class UserIdToken {
|
|||
$args = array(
|
||||
'method' => 'POST',
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $bearer->token(),
|
||||
'Authorization' => $this->client_credentials->credentials(),
|
||||
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||
),
|
||||
);
|
||||
|
|
|
@ -644,10 +644,12 @@ class ApplepayButton {
|
|||
return {
|
||||
action: 'ppcp_update_shipping_method',
|
||||
shipping_method: event.shippingMethod,
|
||||
simplified_contact:
|
||||
this.updatedContactInfo ||
|
||||
this.initialPaymentRequest.shippingContact ||
|
||||
this.initialPaymentRequest.billingContact,
|
||||
simplified_contact: this.hasValidContactInfo(
|
||||
this.updatedContactInfo
|
||||
)
|
||||
? this.updatedContactInfo
|
||||
: this.initialPaymentRequest?.shippingContact ??
|
||||
this.initialPaymentRequest?.billingContact,
|
||||
product_id,
|
||||
products: JSON.stringify( this.products ),
|
||||
caller_page: 'productDetail',
|
||||
|
@ -662,10 +664,12 @@ class ApplepayButton {
|
|||
return {
|
||||
action: 'ppcp_update_shipping_method',
|
||||
shipping_method: event.shippingMethod,
|
||||
simplified_contact:
|
||||
this.updatedContactInfo ||
|
||||
this.initialPaymentRequest.shippingContact ||
|
||||
this.initialPaymentRequest.billingContact,
|
||||
simplified_contact: this.hasValidContactInfo(
|
||||
this.updatedContactInfo
|
||||
)
|
||||
? this.updatedContactInfo
|
||||
: this.initialPaymentRequest?.shippingContact ??
|
||||
this.initialPaymentRequest?.billingContact,
|
||||
caller_page: 'cart',
|
||||
'woocommerce-process-checkout-nonce': this.nonce,
|
||||
};
|
||||
|
@ -948,6 +952,12 @@ class ApplepayButton {
|
|||
|
||||
return btoa( utf8Str );
|
||||
}
|
||||
|
||||
hasValidContactInfo( value ) {
|
||||
return Array.isArray( value )
|
||||
? value.length > 0
|
||||
: Object.keys( value || {} ).length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
export default ApplepayButton;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import ErrorHandler from '../../../../ppcp-button/resources/js/modules/ErrorHandler';
|
||||
import CartActionHandler from '../../../../ppcp-button/resources/js/modules/ActionHandler/CartActionHandler';
|
||||
import { isPayPalSubscription } from '../../../../ppcp-blocks/resources/js/Helper/Subscription';
|
||||
|
||||
class BaseHandler {
|
||||
constructor( buttonConfig, ppcpConfig ) {
|
||||
|
@ -24,7 +23,7 @@ class BaseHandler {
|
|||
}
|
||||
|
||||
shippingAllowed() {
|
||||
return this.buttonConfig.product.needsShipping;
|
||||
return this.buttonConfig.product.needShipping;
|
||||
}
|
||||
|
||||
transactionInfo() {
|
||||
|
@ -76,13 +75,6 @@ class BaseHandler {
|
|||
document.querySelector( '.woocommerce-notices-wrapper' )
|
||||
);
|
||||
}
|
||||
|
||||
errorHandler() {
|
||||
return new ErrorHandler(
|
||||
this.ppcpConfig.labels.error.generic,
|
||||
document.querySelector( '.woocommerce-notices-wrapper' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseHandler;
|
||||
|
|
|
@ -24,32 +24,33 @@ use WooCommerce\PayPalCommerce\Onboarding\State;
|
|||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
return array(
|
||||
'applepay.eligible' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.eligible' => static function ( ContainerInterface $container ): bool {
|
||||
$apm_applies = $container->get( 'applepay.helpers.apm-applies' );
|
||||
assert( $apm_applies instanceof ApmApplies );
|
||||
|
||||
return $apm_applies->for_country_currency();
|
||||
return $apm_applies->for_country() && $apm_applies->for_currency();
|
||||
},
|
||||
'applepay.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies {
|
||||
'applepay.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies {
|
||||
return new ApmApplies(
|
||||
$container->get( 'applepay.supported-country-currency-matrix' ),
|
||||
$container->get( 'applepay.supported-countries' ),
|
||||
$container->get( 'applepay.supported-currencies' ),
|
||||
$container->get( 'api.shop.currency' ),
|
||||
$container->get( 'api.shop.country' )
|
||||
);
|
||||
},
|
||||
'applepay.status-cache' => static function( ContainerInterface $container ): Cache {
|
||||
'applepay.status-cache' => static function( ContainerInterface $container ): Cache {
|
||||
return new Cache( 'ppcp-paypal-apple-status-cache' );
|
||||
},
|
||||
|
||||
// We assume it's a referral if we can check product status without API request failures.
|
||||
'applepay.is_referral' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.is_referral' => static function ( ContainerInterface $container ): bool {
|
||||
$status = $container->get( 'applepay.apple-product-status' );
|
||||
assert( $status instanceof AppleProductStatus );
|
||||
|
||||
return ! $status->has_request_failure();
|
||||
},
|
||||
|
||||
'applepay.availability_notice' => static function ( ContainerInterface $container ): AvailabilityNotice {
|
||||
'applepay.availability_notice' => static function ( ContainerInterface $container ): AvailabilityNotice {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
|
||||
return new AvailabilityNotice(
|
||||
|
@ -63,17 +64,17 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'applepay.has_validated' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.has_validated' => static function ( ContainerInterface $container ): bool {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'applepay_validated' );
|
||||
},
|
||||
|
||||
'applepay.is_validated' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.is_validated' => static function ( ContainerInterface $container ): bool {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'applepay_validated' ) ? $settings->get( 'applepay_validated' ) === true : false;
|
||||
},
|
||||
|
||||
'applepay.apple-product-status' => SingletonDecorator::make(
|
||||
'applepay.apple-product-status' => SingletonDecorator::make(
|
||||
static function( ContainerInterface $container ): AppleProductStatus {
|
||||
return new AppleProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
|
@ -83,7 +84,7 @@ return array(
|
|||
);
|
||||
}
|
||||
),
|
||||
'applepay.available' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.available' => static function ( ContainerInterface $container ): bool {
|
||||
if ( apply_filters( 'woocommerce_paypal_payments_applepay_validate_product_status', true ) ) {
|
||||
$status = $container->get( 'applepay.apple-product-status' );
|
||||
assert( $status instanceof AppleProductStatus );
|
||||
|
@ -94,10 +95,10 @@ return array(
|
|||
}
|
||||
return true;
|
||||
},
|
||||
'applepay.server_supported' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.server_supported' => static function ( ContainerInterface $container ): bool {
|
||||
return ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off';
|
||||
},
|
||||
'applepay.is_browser_supported' => static function ( ContainerInterface $container ): bool {
|
||||
'applepay.is_browser_supported' => static function ( ContainerInterface $container ): bool {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
$user_agent = wp_unslash( $_SERVER['HTTP_USER_AGENT'] ?? '' );
|
||||
if ( $user_agent ) {
|
||||
|
@ -127,7 +128,7 @@ return array(
|
|||
}
|
||||
return false;
|
||||
},
|
||||
'applepay.url' => static function ( ContainerInterface $container ): string {
|
||||
'applepay.url' => static function ( ContainerInterface $container ): string {
|
||||
$path = realpath( __FILE__ );
|
||||
if ( false === $path ) {
|
||||
return '';
|
||||
|
@ -137,13 +138,13 @@ return array(
|
|||
dirname( $path, 3 ) . '/woocommerce-paypal-payments.php'
|
||||
);
|
||||
},
|
||||
'applepay.sdk_script_url' => static function ( ContainerInterface $container ): string {
|
||||
'applepay.sdk_script_url' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://applepay.cdn-apple.com/jsapi/v1/apple-pay-sdk.js';
|
||||
},
|
||||
'applepay.data_to_scripts' => static function ( ContainerInterface $container ): DataToAppleButtonScripts {
|
||||
'applepay.data_to_scripts' => static function ( ContainerInterface $container ): DataToAppleButtonScripts {
|
||||
return new DataToAppleButtonScripts( $container->get( 'applepay.sdk_script_url' ), $container->get( 'wcgateway.settings' ) );
|
||||
},
|
||||
'applepay.button' => static function ( ContainerInterface $container ): ApplePayButton {
|
||||
'applepay.button' => static function ( ContainerInterface $container ): ApplePayButton {
|
||||
return new ApplePayButton(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' ),
|
||||
|
@ -155,7 +156,7 @@ return array(
|
|||
$container->get( 'button.helper.cart-products' )
|
||||
);
|
||||
},
|
||||
'applepay.blocks-payment-method' => static function ( ContainerInterface $container ): PaymentMethodTypeInterface {
|
||||
'applepay.blocks-payment-method' => static function ( ContainerInterface $container ): PaymentMethodTypeInterface {
|
||||
return new BlocksPaymentMethod(
|
||||
'ppcp-applepay',
|
||||
$container->get( 'applepay.url' ),
|
||||
|
@ -164,95 +165,103 @@ return array(
|
|||
$container->get( 'blocks.method' )
|
||||
);
|
||||
},
|
||||
/**
|
||||
* The matrix which countries and currency combinations can be used for ApplePay.
|
||||
*/
|
||||
'applepay.supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array {
|
||||
$default_currencies = array(
|
||||
'AUD',
|
||||
'BRL',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'ILS',
|
||||
'JPY',
|
||||
'MXN',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PHP',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'THB',
|
||||
'TWD',
|
||||
'USD',
|
||||
);
|
||||
|
||||
/**
|
||||
* The list of which countries can be used for ApplePay.
|
||||
*/
|
||||
'applepay.supported-countries' => static function ( ContainerInterface $container ) : array {
|
||||
/**
|
||||
* Returns which countries and currency combinations can be used for ApplePay.
|
||||
* Returns which countries can be used for ApplePay.
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_applepay_supported_country_currency_matrix',
|
||||
'woocommerce_paypal_payments_applepay_supported_countries',
|
||||
// phpcs:disable Squiz.Commenting.InlineComment
|
||||
array(
|
||||
'AU' => $default_currencies,
|
||||
'AT' => $default_currencies,
|
||||
'BE' => $default_currencies,
|
||||
'BG' => $default_currencies,
|
||||
'CA' => $default_currencies,
|
||||
'CY' => $default_currencies,
|
||||
'CZ' => $default_currencies,
|
||||
'DK' => $default_currencies,
|
||||
'EE' => $default_currencies,
|
||||
'FI' => $default_currencies,
|
||||
'FR' => $default_currencies,
|
||||
'DE' => $default_currencies,
|
||||
'GR' => $default_currencies,
|
||||
'HK' => $default_currencies,
|
||||
'HU' => $default_currencies,
|
||||
'IE' => $default_currencies,
|
||||
'IT' => $default_currencies,
|
||||
'LV' => $default_currencies,
|
||||
'LI' => $default_currencies,
|
||||
'LT' => $default_currencies,
|
||||
'LU' => $default_currencies,
|
||||
'MT' => $default_currencies,
|
||||
'NO' => $default_currencies,
|
||||
'NL' => $default_currencies,
|
||||
'PL' => $default_currencies,
|
||||
'PT' => $default_currencies,
|
||||
'RO' => $default_currencies,
|
||||
'SG' => $default_currencies,
|
||||
'SK' => $default_currencies,
|
||||
'SI' => $default_currencies,
|
||||
'ES' => $default_currencies,
|
||||
'SE' => $default_currencies,
|
||||
'GB' => $default_currencies,
|
||||
'US' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'JPY',
|
||||
'USD',
|
||||
),
|
||||
'AU', // Australia
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
'BG', // Bulgaria
|
||||
'CA', // Canada
|
||||
'CN', // China
|
||||
'CY', // Cyprus
|
||||
'CZ', // Czech Republic
|
||||
'DK', // Denmark
|
||||
'EE', // Estonia
|
||||
'FI', // Finland
|
||||
'FR', // France
|
||||
'DE', // Germany
|
||||
'GR', // Greece
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
'LV', // Latvia
|
||||
'LI', // Liechtenstein
|
||||
'LT', // Lithuania
|
||||
'LU', // Luxembourg
|
||||
'MT', // Malta
|
||||
'NL', // Netherlands
|
||||
'NO', // Norway
|
||||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SK', // Slovakia
|
||||
'SI', // Slovenia
|
||||
'ES', // Spain
|
||||
'SE', // Sweden
|
||||
'US', // United States
|
||||
'GB', // United Kingdom
|
||||
)
|
||||
// phpcs:enable Squiz.Commenting.InlineComment
|
||||
);
|
||||
},
|
||||
|
||||
'applepay.enable-url-sandbox' => static function ( ContainerInterface $container ): string {
|
||||
/**
|
||||
* The list of which currencies can be used for ApplePay.
|
||||
*/
|
||||
'applepay.supported-currencies' => static function ( ContainerInterface $container ) : array {
|
||||
/**
|
||||
* Returns which currencies can be used for ApplePay.
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_applepay_supported_currencies',
|
||||
// phpcs:disable Squiz.Commenting.InlineComment
|
||||
array(
|
||||
'AUD', // Australian Dollar
|
||||
'BRL', // Brazilian Real
|
||||
'CAD', // Canadian Dollar
|
||||
'CHF', // Swiss Franc
|
||||
'CZK', // Czech Koruna
|
||||
'DKK', // Danish Krone
|
||||
'EUR', // Euro
|
||||
'GBP', // British Pound Sterling
|
||||
'HKD', // Hong Kong Dollar
|
||||
'HUF', // Hungarian Forint
|
||||
'ILS', // Israeli New Shekel
|
||||
'JPY', // Japanese Yen
|
||||
'MXN', // Mexican Peso
|
||||
'NOK', // Norwegian Krone
|
||||
'NZD', // New Zealand Dollar
|
||||
'PHP', // Philippine Peso
|
||||
'PLN', // Polish Zloty
|
||||
'SEK', // Swedish Krona
|
||||
'SGD', // Singapore Dollar
|
||||
'THB', // Thai Baht
|
||||
'TWD', // New Taiwan Dollar
|
||||
'USD', // United States Dollar
|
||||
)
|
||||
// phpcs:enable Squiz.Commenting.InlineComment
|
||||
);
|
||||
},
|
||||
|
||||
'applepay.enable-url-sandbox' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY';
|
||||
},
|
||||
|
||||
'applepay.enable-url-live' => static function ( ContainerInterface $container ): string {
|
||||
'applepay.enable-url-live' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=APPLE_PAY';
|
||||
},
|
||||
|
||||
'applepay.settings.connection.status-text' => static function ( ContainerInterface $container ): string {
|
||||
'applepay.settings.connection.status-text' => static function ( ContainerInterface $container ): string {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
if ( $state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return '';
|
||||
|
|
|
@ -16,11 +16,18 @@ namespace WooCommerce\PayPalCommerce\Applepay\Helper;
|
|||
class ApmApplies {
|
||||
|
||||
/**
|
||||
* The matrix which countries and currency combinations can be used for ApplePay.
|
||||
* The list of which countries can be used for ApplePay.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $allowed_country_currency_matrix;
|
||||
private $allowed_countries;
|
||||
|
||||
/**
|
||||
* The list of which currencies can be used for ApplePay.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $allowed_currencies;
|
||||
|
||||
/**
|
||||
* 3-letter currency code of the shop.
|
||||
|
@ -37,32 +44,41 @@ class ApmApplies {
|
|||
private $country;
|
||||
|
||||
/**
|
||||
* ApmApplies constructor.
|
||||
* DccApplies constructor.
|
||||
*
|
||||
* @param array $allowed_country_currency_matrix The matrix which countries and currency combinations can be used for ApplePay.
|
||||
* @param array $allowed_countries The list of which countries can be used for ApplePay.
|
||||
* @param array $allowed_currencies The list of which currencies can be used for ApplePay.
|
||||
* @param string $currency 3-letter currency code of the shop.
|
||||
* @param string $country 2-letter country code of the shop.
|
||||
*/
|
||||
public function __construct(
|
||||
array $allowed_country_currency_matrix,
|
||||
array $allowed_countries,
|
||||
array $allowed_currencies,
|
||||
string $currency,
|
||||
string $country
|
||||
) {
|
||||
$this->allowed_country_currency_matrix = $allowed_country_currency_matrix;
|
||||
$this->currency = $currency;
|
||||
$this->country = $country;
|
||||
$this->allowed_countries = $allowed_countries;
|
||||
$this->allowed_currencies = $allowed_currencies;
|
||||
$this->currency = $currency;
|
||||
$this->country = $country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether ApplePay can be used in the current country and the current currency used.
|
||||
* Returns whether ApplePay can be used in the current country used.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function for_country_currency(): bool {
|
||||
if ( ! in_array( $this->country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
return in_array( $this->currency, $this->allowed_country_currency_matrix[ $this->country ], true );
|
||||
public function for_country(): bool {
|
||||
return in_array( $this->country, $this->allowed_countries, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether ApplePay can be used in the current currency used.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function for_currency(): bool {
|
||||
return in_array( $this->currency, $this->allowed_currencies, true );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ return array(
|
|||
->rule()
|
||||
->condition_element( 'axo_enabled', '1' )
|
||||
->action_visible( 'axo_gateway_title' )
|
||||
->action_visible( 'axo_checkout_config_notice' )
|
||||
->action_visible( 'axo_main_notice' )
|
||||
->action_visible( 'axo_privacy' )
|
||||
->action_visible( 'axo_name_on_card' )
|
||||
->action_visible( 'axo_style_heading' )
|
||||
|
@ -114,9 +114,17 @@ return array(
|
|||
),
|
||||
'classes' => array( 'ppcp-valign-label-middle', 'ppcp-align-label-center' ),
|
||||
),
|
||||
'axo_checkout_config_notice' => array(
|
||||
'axo_main_notice' => array(
|
||||
'heading' => '',
|
||||
'html' => $container->get( 'axo.checkout-config-notice' ),
|
||||
'html' => implode(
|
||||
'',
|
||||
array(
|
||||
$container->get( 'axo.settings-conflict-notice' ),
|
||||
$container->get( 'axo.shipping-config-notice' ),
|
||||
$container->get( 'axo.checkout-config-notice' ),
|
||||
$container->get( 'axo.incompatible-plugins-notice' ),
|
||||
)
|
||||
),
|
||||
'type' => 'ppcp-html',
|
||||
'classes' => array( 'ppcp-field-indent' ),
|
||||
'class' => array(),
|
||||
|
|
|
@ -709,6 +709,8 @@ class AxoManager {
|
|||
}`
|
||||
);
|
||||
|
||||
this.emailInput.value = this.stripSpaces( this.emailInput.value );
|
||||
|
||||
this.$( this.el.paymentContainer.selector + '-detail' ).html( '' );
|
||||
this.$( this.el.paymentContainer.selector + '-form' ).html( '' );
|
||||
|
||||
|
@ -1134,6 +1136,10 @@ class AxoManager {
|
|||
return emailPattern.test( value );
|
||||
}
|
||||
|
||||
stripSpaces( str ) {
|
||||
return str.replace( /\s+/g, '' );
|
||||
}
|
||||
|
||||
validateEmail( billingEmail ) {
|
||||
const billingEmailSelector = document.querySelector( billingEmail );
|
||||
const value = document.querySelector( billingEmail + ' input' ).value;
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
export function log( message, level = 'info' ) {
|
||||
const wpDebug = window.wc_ppcp_axo?.wp_debug;
|
||||
const endpoint = window.wc_ppcp_axo?.ajax?.frontend_logger?.endpoint;
|
||||
if ( ! endpoint ) {
|
||||
const loggingEnabled = window.wc_ppcp_axo?.logging_enabled;
|
||||
|
||||
if ( wpDebug ) {
|
||||
switch ( level ) {
|
||||
case 'error':
|
||||
console.error( `[AXO] ${ message }` );
|
||||
break;
|
||||
default:
|
||||
console.log( `[AXO] ${ message }` );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! endpoint || ! loggingEnabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -15,15 +27,5 @@ export function log( message, level = 'info' ) {
|
|||
level,
|
||||
},
|
||||
} ),
|
||||
} ).then( () => {
|
||||
if ( wpDebug ) {
|
||||
switch ( level ) {
|
||||
case 'error':
|
||||
console.error( `[AXO] ${ message }` );
|
||||
break;
|
||||
default:
|
||||
console.log( `[AXO] ${ message }` );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@ namespace WooCommerce\PayPalCommerce\Axo;
|
|||
use WooCommerce\PayPalCommerce\Axo\Assets\AxoManager;
|
||||
use WooCommerce\PayPalCommerce\Axo\Gateway\AxoGateway;
|
||||
use WooCommerce\PayPalCommerce\Axo\Helper\ApmApplies;
|
||||
use WooCommerce\PayPalCommerce\Axo\Helper\SettingsNoticeGenerator;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
return array(
|
||||
|
@ -25,7 +25,7 @@ return array(
|
|||
$apm_applies = $container->get( 'axo.helpers.apm-applies' );
|
||||
assert( $apm_applies instanceof ApmApplies );
|
||||
|
||||
return $apm_applies->for_country_currency() && $apm_applies->for_settings();
|
||||
return $apm_applies->for_country_currency();
|
||||
},
|
||||
|
||||
'axo.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies {
|
||||
|
@ -36,6 +36,10 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'axo.helpers.settings-notice-generator' => static function ( ContainerInterface $container ) : SettingsNoticeGenerator {
|
||||
return new SettingsNoticeGenerator();
|
||||
},
|
||||
|
||||
// If AXO is configured and onboarded.
|
||||
'axo.available' => static function ( ContainerInterface $container ): bool {
|
||||
return true;
|
||||
|
@ -159,48 +163,35 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'axo.settings-conflict-notice' => static function ( ContainerInterface $container ) : string {
|
||||
$settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' );
|
||||
assert( $settings_notice_generator instanceof SettingsNoticeGenerator );
|
||||
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
return $settings_notice_generator->generate_settings_conflict_notice( $settings );
|
||||
},
|
||||
|
||||
'axo.checkout-config-notice' => static function ( ContainerInterface $container ) : string {
|
||||
$checkout_page_link = esc_url( get_edit_post_link( wc_get_page_id( 'checkout' ) ) ?? '' );
|
||||
$block_checkout_docs_link = __(
|
||||
'https://woocommerce.com/document/cart-checkout-blocks-status/#reverting-to-the-cart-and-checkout-shortcodes',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
$settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' );
|
||||
assert( $settings_notice_generator instanceof SettingsNoticeGenerator );
|
||||
|
||||
if ( CartCheckoutDetector::has_elementor_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store currently uses the <code>Elementor Checkout widget</code>. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
} elseif ( CartCheckoutDetector::has_block_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store currently uses the WooCommerce <code>Checkout</code> block. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
} elseif ( ! CartCheckoutDetector::has_classic_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store does not seem to be properly configured or uses an incompatible <code>third-party Checkout</code> solution. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
return $settings_notice_generator->generate_checkout_notice();
|
||||
},
|
||||
|
||||
return '<div class="ppcp-notice ppcp-notice-error"><p>' . $notice_content . '</p></div>';
|
||||
'axo.shipping-config-notice' => static function ( ContainerInterface $container ) : string {
|
||||
$settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' );
|
||||
assert( $settings_notice_generator instanceof SettingsNoticeGenerator );
|
||||
|
||||
return $settings_notice_generator->generate_shipping_notice();
|
||||
},
|
||||
|
||||
'axo.incompatible-plugins-notice' => static function ( ContainerInterface $container ) : string {
|
||||
$settings_notice_generator = $container->get( 'axo.helpers.settings-notice-generator' );
|
||||
assert( $settings_notice_generator instanceof SettingsNoticeGenerator );
|
||||
|
||||
return $settings_notice_generator->generate_incompatible_plugins_notice();
|
||||
},
|
||||
|
||||
'axo.smart-button-location-notice' => static function ( ContainerInterface $container ) : string {
|
||||
|
@ -230,6 +221,7 @@ return array(
|
|||
|
||||
return '<div class="ppcp-notice ppcp-notice-warning"><p>' . $notice_content . '</p></div>';
|
||||
},
|
||||
|
||||
'axo.endpoint.frontend-logger' => static function ( ContainerInterface $container ): FrontendLoggerEndpoint {
|
||||
return new FrontendLoggerEndpoint(
|
||||
$container->get( 'button.request-data' ),
|
||||
|
|
|
@ -216,6 +216,7 @@ class AxoManager {
|
|||
'nonce' => wp_create_nonce( FrontendLoggerEndpoint::nonce() ),
|
||||
),
|
||||
),
|
||||
'logging_enabled' => $this->settings->has( 'logging_enabled' ) ? $this->settings->get( 'logging_enabled' ) : '',
|
||||
'wp_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
|
||||
'billing_email_button_text' => __( 'Continue', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
|
|
|
@ -66,7 +66,7 @@ class AxoModule implements ModuleInterface {
|
|||
|
||||
// Add the gateway in admin area.
|
||||
if ( is_admin() ) {
|
||||
$methods[] = $gateway;
|
||||
// $methods[] = $gateway; - Temporarily remove Fastlane from the payment gateway list in admin area.
|
||||
return $methods;
|
||||
}
|
||||
|
||||
|
@ -77,9 +77,10 @@ class AxoModule implements ModuleInterface {
|
|||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$is_paypal_enabled = $settings->has( 'enabled' ) && $settings->get( 'enabled' ) ?? false;
|
||||
$is_dcc_enabled = $settings->has( 'dcc_enabled' ) && $settings->get( 'dcc_enabled' ) ?? false;
|
||||
|
||||
if ( ! $is_dcc_enabled ) {
|
||||
if ( ! $is_paypal_enabled || ! $is_dcc_enabled ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
|
@ -87,6 +88,10 @@ class AxoModule implements ModuleInterface {
|
|||
return $methods;
|
||||
}
|
||||
|
||||
if ( ! $this->is_compatible_shipping_config() ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
$methods[] = $gateway;
|
||||
return $methods;
|
||||
},
|
||||
|
@ -144,13 +149,20 @@ class AxoModule implements ModuleInterface {
|
|||
function () use ( $c ) {
|
||||
$module = $this;
|
||||
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$is_paypal_enabled = $settings->has( 'enabled' ) && $settings->get( 'enabled' ) ?? false;
|
||||
|
||||
$subscription_helper = $c->get( 'wc-subscriptions.helper' );
|
||||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
// Check if the module is applicable, correct country, currency, ... etc.
|
||||
if ( ! $c->get( 'axo.eligible' )
|
||||
if ( ! $is_paypal_enabled
|
||||
|| ! $c->get( 'axo.eligible' )
|
||||
|| 'continuation' === $c->get( 'button.context' )
|
||||
|| $subscription_helper->cart_contains_subscription() ) {
|
||||
|| $subscription_helper->cart_contains_subscription()
|
||||
|| ! $this->is_compatible_shipping_config() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -194,9 +206,17 @@ class AxoModule implements ModuleInterface {
|
|||
|
||||
add_action(
|
||||
'wp_head',
|
||||
function () {
|
||||
function () use ( $c ) {
|
||||
// phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript
|
||||
echo '<script async src="https://www.paypalobjects.com/insights/v1/paypal-insights.sandbox.min.js"></script>';
|
||||
|
||||
// Add meta tag to allow feature-detection of the site's AXO payment state.
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$this->add_feature_detection_tag(
|
||||
$settings->has( 'axo_enabled' ) && $settings->get( 'axo_enabled' )
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -280,15 +300,7 @@ class AxoModule implements ModuleInterface {
|
|||
array $localized_script_data
|
||||
): array {
|
||||
try {
|
||||
$target_customer_id = '';
|
||||
if ( is_user_logged_in() ) {
|
||||
$target_customer_id = get_user_meta( get_current_user_id(), '_ppcp_target_customer_id', true );
|
||||
if ( ! $target_customer_id ) {
|
||||
$target_customer_id = get_user_meta( get_current_user_id(), 'ppcp_customer_id', true );
|
||||
}
|
||||
}
|
||||
|
||||
$sdk_client_token = $api->sdk_client_token( $target_customer_id );
|
||||
$sdk_client_token = $api->sdk_client_token();
|
||||
$localized_script_data['axo'] = array(
|
||||
'sdk_client_token' => $sdk_client_token,
|
||||
);
|
||||
|
@ -341,6 +353,7 @@ class AxoModule implements ModuleInterface {
|
|||
|
||||
return ! is_user_logged_in()
|
||||
&& CartCheckoutDetector::has_classic_checkout()
|
||||
&& $this->is_compatible_shipping_config()
|
||||
&& $is_axo_enabled
|
||||
&& $is_dcc_enabled
|
||||
&& ! $this->is_excluded_endpoint();
|
||||
|
@ -396,4 +409,32 @@ class AxoModule implements ModuleInterface {
|
|||
// Exclude the Order Pay endpoint.
|
||||
return is_wc_endpoint_url( 'order-pay' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Condition to evaluate if the shipping configuration is compatible.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_compatible_shipping_config(): bool {
|
||||
return ! wc_shipping_enabled() || ( wc_shipping_enabled() && ! wc_ship_to_billing_address_only() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a meta tag to allow feature detection on certain pages.
|
||||
*
|
||||
* @param bool $axo_enabled Whether the gateway is enabled.
|
||||
* @return void
|
||||
*/
|
||||
private function add_feature_detection_tag( bool $axo_enabled ) {
|
||||
$show_tag = is_checkout() || is_cart() || is_shop();
|
||||
|
||||
if ( ! $show_tag ) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<meta name="ppcp.axo" content="ppcp.axo.%s" />',
|
||||
$axo_enabled ? 'enabled' : 'disabled'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ class AxoGateway extends WC_Payment_Gateway {
|
|||
? $this->ppcp_settings->get( 'axo_gateway_title' )
|
||||
: $this->get_option( 'title', $this->method_title );
|
||||
|
||||
$this->description = __( 'Enter your email address to continue.', 'woocommerce-paypal-payments' );
|
||||
$this->description = __( 'Enter your email address above to continue.', 'woocommerce-paypal-payments' );
|
||||
|
||||
$this->init_form_fields();
|
||||
$this->init_settings();
|
||||
|
|
|
@ -64,19 +64,4 @@ class ApmApplies {
|
|||
}
|
||||
return in_array( $this->currency, $this->allowed_country_currency_matrix[ $this->country ], true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the settings are compatible with AXO.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function for_settings(): bool {
|
||||
if ( get_option( 'woocommerce_ship_to_destination' ) === 'billing_only' ) { // Force shipping to the customer billing address.
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
179
modules/ppcp-axo/src/Helper/SettingsNoticeGenerator.php
Normal file
179
modules/ppcp-axo/src/Helper/SettingsNoticeGenerator.php
Normal file
|
@ -0,0 +1,179 @@
|
|||
<?php
|
||||
/**
|
||||
* Settings notice generator.
|
||||
* Generates the settings notices.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Axo\Helper
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Axo\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
|
||||
/**
|
||||
* Class SettingsNoticeGenerator
|
||||
*/
|
||||
class SettingsNoticeGenerator {
|
||||
/**
|
||||
* Generates the full HTML of the notification.
|
||||
*
|
||||
* @param string $message HTML of the inner message contents.
|
||||
* @param bool $is_error Whether the provided message is an error. Affects the notice color.
|
||||
*
|
||||
* @return string The full HTML code of the notification, or an empty string.
|
||||
*/
|
||||
private function render_notice( string $message, bool $is_error = false ) : string {
|
||||
if ( ! $message ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<div class="ppcp-notice %1$s"><p>%2$s</p></div>',
|
||||
$is_error ? 'ppcp-notice-error' : '',
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the checkout notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_checkout_notice(): string {
|
||||
$checkout_page_link = esc_url( get_edit_post_link( wc_get_page_id( 'checkout' ) ) ?? '' );
|
||||
$block_checkout_docs_link = __(
|
||||
'https://woocommerce.com/document/cart-checkout-blocks-status/#reverting-to-the-cart-and-checkout-shortcodes',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
|
||||
$notice_content = '';
|
||||
|
||||
if ( CartCheckoutDetector::has_elementor_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store currently uses the <code>Elementor Checkout widget</code>. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
} elseif ( CartCheckoutDetector::has_block_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store currently uses the WooCommerce <code>Checkout</code> block. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
} elseif ( ! CartCheckoutDetector::has_classic_checkout() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Checkout edit page. %2$s: URL to the block checkout docs. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Checkout page</a> of your store does not seem to be properly configured or uses an incompatible <code>third-party Checkout</code> solution. To enable Fastlane and accelerate payments, the page must include either the <code>Classic Checkout</code> or the <code>[woocommerce_checkout]</code> shortcode. See <a href="%2$s">this page</a> for instructions on how to switch to the classic layout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $checkout_page_link ),
|
||||
esc_url( $block_checkout_docs_link )
|
||||
);
|
||||
}
|
||||
|
||||
return $notice_content ? '<div class="ppcp-notice ppcp-notice-error"><p>' . $notice_content . '</p></div>' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the shipping notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_shipping_notice(): string {
|
||||
$shipping_settings_link = admin_url( 'admin.php?page=wc-settings&tab=shipping§ion=options' );
|
||||
|
||||
$notice_content = '';
|
||||
|
||||
if ( wc_shipping_enabled() && wc_ship_to_billing_address_only() ) {
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the Shipping destination settings page. */
|
||||
__(
|
||||
'<span class="highlight">Warning:</span> The <a href="%1$s">Shipping destination</a> of your store is currently configured to <code>Force shipping to the customer billing address</code>. To enable Fastlane and accelerate payments, the shipping destination must be configured either to <code>Default to customer shipping address</code> or <code>Default to customer billing address</code> so buyers can set separate billing and shipping details.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
esc_url( $shipping_settings_link )
|
||||
);
|
||||
}
|
||||
|
||||
return $notice_content ? '<div class="ppcp-notice ppcp-notice-error"><p>' . $notice_content . '</p></div>' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the incompatible plugins notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generate_incompatible_plugins_notice(): string {
|
||||
$incompatible_plugins = array(
|
||||
'Elementor' => did_action( 'elementor/loaded' ),
|
||||
'CheckoutWC' => defined( 'CFW_NAME' ),
|
||||
);
|
||||
|
||||
$active_plugins_list = array_filter( $incompatible_plugins );
|
||||
|
||||
if ( empty( $active_plugins_list ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$incompatible_plugin_items = array_map(
|
||||
function ( $plugin ) {
|
||||
return "<li>{$plugin}</li>";
|
||||
},
|
||||
array_keys( $active_plugins_list )
|
||||
);
|
||||
|
||||
$plugins_settings_link = esc_url( admin_url( 'plugins.php' ) );
|
||||
$notice_content = sprintf(
|
||||
/* translators: %1$s: URL to the plugins settings page. %2$s: List of incompatible plugins. */
|
||||
__(
|
||||
'<span class="highlight">Note:</span> The accelerated guest buyer experience provided by Fastlane may not be fully compatible with some of the following <a href="%1$s">active plugins</a>: <ul class="ppcp-notice-list">%2$s</ul>',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
$plugins_settings_link,
|
||||
implode( '', $incompatible_plugin_items )
|
||||
);
|
||||
|
||||
return '<div class="ppcp-notice"><p>' . $notice_content . '</p></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a warning notice with instructions on conflicting plugin-internal settings.
|
||||
*
|
||||
* @param Settings $settings The plugin settings container, which is checked for conflicting
|
||||
* values.
|
||||
* @return string
|
||||
*/
|
||||
public function generate_settings_conflict_notice( Settings $settings ) : string {
|
||||
$notice_content = '';
|
||||
$is_dcc_enabled = false;
|
||||
|
||||
try {
|
||||
$is_dcc_enabled = $settings->has( 'dcc_enabled' ) && $settings->get( 'dcc_enabled' );
|
||||
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
|
||||
} catch ( NotFoundException $ignored ) {
|
||||
// Never happens.
|
||||
}
|
||||
|
||||
if ( ! $is_dcc_enabled ) {
|
||||
$notice_content = __(
|
||||
'<span class="highlight">Warning:</span> To enable Fastlane and accelerate payments, the <strong>Advanced Card Processing</strong> payment method must also be enabled.',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render_notice( $notice_content, true );
|
||||
}
|
||||
}
|
|
@ -52,7 +52,7 @@ class AdvancedCardPaymentMethod extends AbstractPaymentMethodType {
|
|||
*
|
||||
* @var Settings
|
||||
*/
|
||||
protected $settings;
|
||||
protected $plugin_settings;
|
||||
|
||||
/**
|
||||
* AdvancedCardPaymentMethod constructor.
|
||||
|
@ -70,12 +70,12 @@ class AdvancedCardPaymentMethod extends AbstractPaymentMethodType {
|
|||
$smart_button,
|
||||
Settings $settings
|
||||
) {
|
||||
$this->name = CreditCardGateway::ID;
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->gateway = $gateway;
|
||||
$this->smart_button = $smart_button;
|
||||
$this->settings = $settings;
|
||||
$this->name = CreditCardGateway::ID;
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->gateway = $gateway;
|
||||
$this->smart_button = $smart_button;
|
||||
$this->plugin_settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,8 +118,8 @@ class AdvancedCardPaymentMethod extends AbstractPaymentMethodType {
|
|||
'scriptData' => $script_data,
|
||||
'supports' => $this->gateway->supports,
|
||||
'save_card_text' => esc_html__( 'Save your card', 'woocommerce-paypal-payments' ),
|
||||
'is_vaulting_enabled' => $this->settings->has( 'vault_enabled_dcc' ) && $this->settings->get( 'vault_enabled_dcc' ),
|
||||
'card_icons' => $this->settings->has( 'card_icons' ) ? (array) $this->settings->get( 'card_icons' ) : array(),
|
||||
'is_vaulting_enabled' => $this->plugin_settings->has( 'vault_enabled_dcc' ) && $this->plugin_settings->get( 'vault_enabled_dcc' ),
|
||||
'card_icons' => $this->plugin_settings->has( 'card_icons' ) ? (array) $this->plugin_settings->get( 'card_icons' ) : array(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -181,9 +181,14 @@ class CheckoutBootstap {
|
|||
const isSeparateButtonGateway = [ PaymentMethods.CARD_BUTTON ].includes(
|
||||
currentPaymentMethod
|
||||
);
|
||||
const isGooglePayMethod =
|
||||
currentPaymentMethod === PaymentMethods.GOOGLEPAY;
|
||||
const isSavedCard = isCard && isSavedCardSelected();
|
||||
const isNotOurGateway =
|
||||
! isPaypal && ! isCard && ! isSeparateButtonGateway;
|
||||
! isPaypal &&
|
||||
! isCard &&
|
||||
! isSeparateButtonGateway &&
|
||||
! isGooglePayMethod;
|
||||
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
||||
const hasVaultedPaypal =
|
||||
PayPalCommerceGateway.vaulted_paypal_email !== '';
|
||||
|
@ -227,6 +232,8 @@ class CheckoutBootstap {
|
|||
}
|
||||
}
|
||||
|
||||
setVisible( '#ppc-button-ppcp-googlepay', isGooglePayMethod );
|
||||
|
||||
jQuery( document.body ).trigger( 'ppcp_checkout_rendered' );
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { getPlanIdFromVariation } from '../Helper/Subscriptions';
|
|||
import SimulateCart from '../Helper/SimulateCart';
|
||||
import { strRemoveWord, strAddWord, throttle } from '../Helper/Utils';
|
||||
import merge from 'deepmerge';
|
||||
import { debounce } from '../../../../../ppcp-blocks/resources/js/Helper/debounce';
|
||||
|
||||
class SingleProductBootstap {
|
||||
constructor( gateway, renderer, errorHandler ) {
|
||||
|
@ -20,9 +21,13 @@ class SingleProductBootstap {
|
|||
|
||||
// Prevent simulate cart being called too many times in a burst.
|
||||
this.simulateCartThrottled = throttle(
|
||||
this.simulateCart,
|
||||
this.simulateCart.bind( this ),
|
||||
this.gateway.simulate_cart.throttling || 5000
|
||||
);
|
||||
this.debouncedHandleChange = debounce(
|
||||
this.handleChange.bind( this ),
|
||||
100
|
||||
);
|
||||
|
||||
this.renderer.onButtonsInit(
|
||||
this.gateway.button.wrapper,
|
||||
|
@ -74,7 +79,7 @@ class SingleProductBootstap {
|
|||
}
|
||||
|
||||
jQuery( document ).on( 'change', this.formSelector, () => {
|
||||
this.handleChange();
|
||||
this.debouncedHandleChange();
|
||||
} );
|
||||
this.mutationObserver.observe( form, {
|
||||
childList: true,
|
||||
|
|
|
@ -3,6 +3,7 @@ export const PaymentMethods = {
|
|||
CARDS: 'ppcp-credit-card-gateway',
|
||||
OXXO: 'ppcp-oxxo-gateway',
|
||||
CARD_BUTTON: 'ppcp-card-button-gateway',
|
||||
GOOGLEPAY: 'ppcp-googlepay',
|
||||
};
|
||||
|
||||
export const ORDER_BUTTON_SELECTOR = '#place_order';
|
||||
|
|
|
@ -71,7 +71,10 @@ export const loadPaypalScript = ( config, onLoaded, onError = null ) => {
|
|||
}
|
||||
|
||||
// Load PayPal script for special case with data-client-token
|
||||
if ( config.data_client_id?.set_attribute ) {
|
||||
if (
|
||||
config.data_client_id?.set_attribute &&
|
||||
config.vault_v3_enabled !== '1'
|
||||
) {
|
||||
dataClientIdAttributeHandler(
|
||||
scriptOptions,
|
||||
config.data_client_id,
|
||||
|
|
|
@ -14,8 +14,10 @@ use WC_Cart;
|
|||
use WC_Order;
|
||||
use WC_Order_Item_Product;
|
||||
use WC_Order_Item_Shipping;
|
||||
use WC_Product;
|
||||
use WC_Subscription;
|
||||
use WC_Subscriptions_Product;
|
||||
use WC_Tax;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Shipping;
|
||||
|
@ -106,6 +108,7 @@ class WooCommerceOrderCreator {
|
|||
* @param Payer|null $payer The payer.
|
||||
* @param Shipping|null $shipping The shipping.
|
||||
* @return void
|
||||
* @psalm-suppress InvalidScalarArgument
|
||||
*/
|
||||
protected function configure_line_items( WC_Order $wc_order, WC_Cart $wc_cart, ?Payer $payer, ?Shipping $shipping ): void {
|
||||
$cart_contents = $wc_cart->get_cart();
|
||||
|
@ -130,18 +133,21 @@ class WooCommerceOrderCreator {
|
|||
return;
|
||||
}
|
||||
|
||||
$total = $product->get_price() * $quantity;
|
||||
$subtotal = wc_get_price_excluding_tax( $product, array( 'qty' => $quantity ) );
|
||||
$subtotal = apply_filters( 'woocommerce_paypal_payments_shipping_callback_cart_line_item_total', $subtotal, $cart_item );
|
||||
|
||||
$item->set_name( $product->get_name() );
|
||||
$item->set_subtotal( $total );
|
||||
$item->set_total( $total );
|
||||
$item->set_subtotal( $subtotal );
|
||||
$item->set_total( $subtotal );
|
||||
|
||||
$this->configure_taxes( $product, $item, $subtotal );
|
||||
|
||||
$product_id = $product->get_id();
|
||||
|
||||
if ( $this->is_subscription( $product_id ) ) {
|
||||
$subscription = $this->create_subscription( $wc_order, $product_id );
|
||||
$sign_up_fee = WC_Subscriptions_Product::get_sign_up_fee( $product );
|
||||
$subscription_total = $total + $sign_up_fee;
|
||||
$subscription_total = (float) $subtotal + (float) $sign_up_fee;
|
||||
|
||||
$item->set_subtotal( $subscription_total );
|
||||
$item->set_total( $subscription_total );
|
||||
|
@ -282,6 +288,23 @@ class WooCommerceOrderCreator {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the taxes.
|
||||
*
|
||||
* @param WC_Product $product The Product.
|
||||
* @param WC_Order_Item_Product $item The line item.
|
||||
* @param float|string $subtotal The subtotal.
|
||||
* @return void
|
||||
* @psalm-suppress InvalidScalarArgument
|
||||
*/
|
||||
protected function configure_taxes( WC_Product $product, WC_Order_Item_Product $item, $subtotal ): void {
|
||||
$tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
|
||||
$taxes = WC_Tax::calc_tax( $subtotal, $tax_rates, true );
|
||||
|
||||
$item->set_tax_class( $product->get_tax_class() );
|
||||
$item->set_total_tax( (float) array_sum( $taxes ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the product with given ID is WC subscription.
|
||||
*
|
||||
|
|
|
@ -83,6 +83,9 @@ return array(
|
|||
'compat.wc_shipping_tax.is_supported_plugin_version_active' => function (): bool {
|
||||
return class_exists( 'WC_Connect_Loader' );
|
||||
},
|
||||
'compat.nyp.is_supported_plugin_version_active' => function (): bool {
|
||||
return function_exists( 'wc_nyp_init' );
|
||||
},
|
||||
|
||||
'compat.module.url' => static function ( ContainerInterface $container ): string {
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,11 @@ class CompatModule implements ModuleInterface {
|
|||
$this->fix_page_builders();
|
||||
$this->exclude_cache_plugins_js_minification( $c );
|
||||
$this->set_elementor_checkout_context();
|
||||
|
||||
$is_nyp_active = $c->get( 'compat.nyp.is_supported_plugin_version_active' );
|
||||
if ( $is_nyp_active ) {
|
||||
$this->initialize_nyp_compat_layer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -387,4 +392,24 @@ class CompatModule implements ModuleInterface {
|
|||
3
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the compatibility layer for PayPal Shipping callback & WooCommerce Name Your Price plugin.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initialize_nyp_compat_layer(): void {
|
||||
add_filter(
|
||||
'woocommerce_paypal_payments_shipping_callback_cart_line_item_total',
|
||||
static function( string $total, array $cart_item ) {
|
||||
if ( ! isset( $cart_item['nyp'] ) ) {
|
||||
return $total;
|
||||
}
|
||||
|
||||
return $cart_item['nyp'];
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,3 +13,7 @@
|
|||
min-width: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#ppc-button-ppcp-googlepay {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import CheckoutActionHandler from '../../../../ppcp-button/resources/js/modules/
|
|||
import FormValidator from '../../../../ppcp-button/resources/js/modules/Helper/FormValidator';
|
||||
|
||||
class CheckoutHandler extends BaseHandler {
|
||||
transactionInfo() {
|
||||
validateForm() {
|
||||
return new Promise( async ( resolve, reject ) => {
|
||||
try {
|
||||
const spinner = new Spinner();
|
||||
|
@ -23,7 +23,7 @@ class CheckoutHandler extends BaseHandler {
|
|||
: null;
|
||||
|
||||
if ( ! formValidator ) {
|
||||
resolve( super.transactionInfo() );
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ class CheckoutHandler extends BaseHandler {
|
|||
|
||||
reject();
|
||||
} else {
|
||||
resolve( super.transactionInfo() );
|
||||
resolve();
|
||||
}
|
||||
} );
|
||||
} catch ( error ) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||
import { setVisible } from '../../../ppcp-button/resources/js/modules/Helper/Hiding';
|
||||
import { setEnabled } from '../../../ppcp-button/resources/js/modules/Helper/ButtonDisabler';
|
||||
import widgetBuilder from '../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder';
|
||||
|
@ -6,7 +5,13 @@ import UpdatePaymentData from './Helper/UpdatePaymentData';
|
|||
import { apmButtonsInit } from '../../../ppcp-button/resources/js/modules/Helper/ApmButtons';
|
||||
|
||||
class GooglepayButton {
|
||||
constructor( context, externalHandler, buttonConfig, ppcpConfig ) {
|
||||
constructor(
|
||||
context,
|
||||
externalHandler,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
contextHandler
|
||||
) {
|
||||
apmButtonsInit( ppcpConfig );
|
||||
|
||||
this.isInitialized = false;
|
||||
|
@ -15,16 +20,10 @@ class GooglepayButton {
|
|||
this.externalHandler = externalHandler;
|
||||
this.buttonConfig = buttonConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
this.contextHandler = contextHandler;
|
||||
|
||||
this.paymentsClient = null;
|
||||
|
||||
this.contextHandler = ContextHandlerFactory.create(
|
||||
this.context,
|
||||
this.buttonConfig,
|
||||
this.ppcpConfig,
|
||||
this.externalHandler
|
||||
);
|
||||
|
||||
this.log = function () {
|
||||
if ( this.buttonConfig.is_debug ) {
|
||||
//console.log('[GooglePayButton]', ...arguments);
|
||||
|
@ -32,7 +31,7 @@ class GooglepayButton {
|
|||
};
|
||||
}
|
||||
|
||||
init( config ) {
|
||||
init( config, transactionInfo ) {
|
||||
if ( this.isInitialized ) {
|
||||
return;
|
||||
}
|
||||
|
@ -47,6 +46,7 @@ class GooglepayButton {
|
|||
}
|
||||
|
||||
this.googlePayConfig = config;
|
||||
this.transactionInfo = transactionInfo;
|
||||
this.allowedPaymentMethods = config.allowedPaymentMethods;
|
||||
this.baseCardPaymentMethod = this.allowedPaymentMethods[ 0 ];
|
||||
|
||||
|
@ -62,6 +62,39 @@ class GooglepayButton {
|
|||
)
|
||||
.then( ( response ) => {
|
||||
if ( response.result ) {
|
||||
if (
|
||||
( this.context === 'checkout' ||
|
||||
this.context === 'pay-now' ) &&
|
||||
this.buttonConfig.is_wc_gateway_enabled === '1'
|
||||
) {
|
||||
const wrapper = document.getElementById(
|
||||
'ppc-button-ppcp-googlepay'
|
||||
);
|
||||
|
||||
if ( wrapper ) {
|
||||
const { ppcpStyle, buttonStyle } =
|
||||
this.contextConfig();
|
||||
|
||||
wrapper.classList.add(
|
||||
`ppcp-button-${ ppcpStyle.shape }`,
|
||||
'ppcp-button-apm',
|
||||
'ppcp-button-googlepay'
|
||||
);
|
||||
|
||||
if ( ppcpStyle.height ) {
|
||||
wrapper.style.height = `${ ppcpStyle.height }px`;
|
||||
}
|
||||
|
||||
this.addButtonCheckout(
|
||||
this.baseCardPaymentMethod,
|
||||
wrapper,
|
||||
buttonStyle
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.addButton( this.baseCardPaymentMethod );
|
||||
}
|
||||
} )
|
||||
|
@ -76,7 +109,7 @@ class GooglepayButton {
|
|||
}
|
||||
|
||||
this.isInitialized = false;
|
||||
this.init( this.googlePayConfig );
|
||||
this.init( this.googlePayConfig, this.transactionInfo );
|
||||
}
|
||||
|
||||
validateConfig() {
|
||||
|
@ -221,6 +254,19 @@ class GooglepayButton {
|
|||
} );
|
||||
}
|
||||
|
||||
addButtonCheckout( baseCardPaymentMethod, wrapper, buttonStyle ) {
|
||||
const button = this.paymentsClient.createButton( {
|
||||
onClick: this.onButtonClick.bind( this ),
|
||||
allowedPaymentMethods: [ baseCardPaymentMethod ],
|
||||
buttonColor: buttonStyle.color || 'black',
|
||||
buttonType: buttonStyle.type || 'pay',
|
||||
buttonLocale: buttonStyle.language || 'en',
|
||||
buttonSizeMode: 'fill',
|
||||
} );
|
||||
|
||||
wrapper.appendChild( button );
|
||||
}
|
||||
|
||||
waitForWrapper( selector, callback, delay = 100, timeout = 2000 ) {
|
||||
const startTime = Date.now();
|
||||
const interval = setInterval( () => {
|
||||
|
@ -243,22 +289,39 @@ class GooglepayButton {
|
|||
/**
|
||||
* Show Google Pay payment sheet when Google Pay payment button is clicked
|
||||
*/
|
||||
async onButtonClick() {
|
||||
onButtonClick() {
|
||||
this.log( 'onButtonClick', this.context );
|
||||
|
||||
const paymentDataRequest = await this.paymentDataRequest();
|
||||
this.log(
|
||||
'onButtonClick: paymentDataRequest',
|
||||
paymentDataRequest,
|
||||
this.context
|
||||
);
|
||||
const initiatePaymentRequest = () => {
|
||||
window.ppcpFundingSource = 'googlepay';
|
||||
|
||||
window.ppcpFundingSource = 'googlepay'; // Do this on another place like on create order endpoint handler.
|
||||
const paymentDataRequest = this.paymentDataRequest();
|
||||
|
||||
this.paymentsClient.loadPaymentData( paymentDataRequest );
|
||||
this.log(
|
||||
'onButtonClick: paymentDataRequest',
|
||||
paymentDataRequest,
|
||||
this.context
|
||||
);
|
||||
|
||||
this.paymentsClient.loadPaymentData( paymentDataRequest );
|
||||
};
|
||||
|
||||
if ( 'function' === typeof this.contextHandler.validateForm ) {
|
||||
// During regular checkout, validate the checkout form before initiating the payment.
|
||||
this.contextHandler
|
||||
.validateForm()
|
||||
.then( initiatePaymentRequest, () => {
|
||||
console.error(
|
||||
'[GooglePayButton] Form validation failed.'
|
||||
);
|
||||
} );
|
||||
} else {
|
||||
// This is the flow on product page, cart, and other non-checkout pages.
|
||||
initiatePaymentRequest();
|
||||
}
|
||||
}
|
||||
|
||||
async paymentDataRequest() {
|
||||
paymentDataRequest() {
|
||||
const baseRequest = {
|
||||
apiVersion: 2,
|
||||
apiVersionMinor: 0,
|
||||
|
@ -268,8 +331,7 @@ class GooglepayButton {
|
|||
const paymentDataRequest = Object.assign( {}, baseRequest );
|
||||
paymentDataRequest.allowedPaymentMethods =
|
||||
googlePayConfig.allowedPaymentMethods;
|
||||
paymentDataRequest.transactionInfo =
|
||||
await this.contextHandler.transactionInfo();
|
||||
paymentDataRequest.transactionInfo = this.transactionInfo;
|
||||
paymentDataRequest.merchantInfo = googlePayConfig.merchantInfo;
|
||||
|
||||
if (
|
||||
|
@ -308,43 +370,51 @@ class GooglepayButton {
|
|||
this.log( 'paymentData', paymentData );
|
||||
|
||||
return new Promise( async ( resolve, reject ) => {
|
||||
const paymentDataRequestUpdate = {};
|
||||
try {
|
||||
const paymentDataRequestUpdate = {};
|
||||
|
||||
const updatedData = await new UpdatePaymentData(
|
||||
this.buttonConfig.ajax.update_payment_data
|
||||
).update( paymentData );
|
||||
const transactionInfo = await this.contextHandler.transactionInfo();
|
||||
const updatedData = await new UpdatePaymentData(
|
||||
this.buttonConfig.ajax.update_payment_data
|
||||
).update( paymentData );
|
||||
const transactionInfo = this.transactionInfo;
|
||||
|
||||
this.log( 'onPaymentDataChanged:updatedData', updatedData );
|
||||
this.log( 'onPaymentDataChanged:transactionInfo', transactionInfo );
|
||||
this.log( 'onPaymentDataChanged:updatedData', updatedData );
|
||||
this.log(
|
||||
'onPaymentDataChanged:transactionInfo',
|
||||
transactionInfo
|
||||
);
|
||||
|
||||
updatedData.country_code = transactionInfo.countryCode;
|
||||
updatedData.currency_code = transactionInfo.currencyCode;
|
||||
updatedData.total_str = transactionInfo.totalPrice;
|
||||
updatedData.country_code = transactionInfo.countryCode;
|
||||
updatedData.currency_code = transactionInfo.currencyCode;
|
||||
updatedData.total_str = transactionInfo.totalPrice;
|
||||
|
||||
// Handle unserviceable address.
|
||||
if ( ! updatedData.shipping_options?.shippingOptions?.length ) {
|
||||
paymentDataRequestUpdate.error =
|
||||
this.unserviceableShippingAddressError();
|
||||
resolve( paymentDataRequestUpdate );
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( paymentData.callbackTrigger ) {
|
||||
case 'INITIALIZE':
|
||||
case 'SHIPPING_ADDRESS':
|
||||
paymentDataRequestUpdate.newShippingOptionParameters =
|
||||
updatedData.shipping_options;
|
||||
paymentDataRequestUpdate.newTransactionInfo =
|
||||
this.calculateNewTransactionInfo( updatedData );
|
||||
break;
|
||||
case 'SHIPPING_OPTION':
|
||||
paymentDataRequestUpdate.newTransactionInfo =
|
||||
this.calculateNewTransactionInfo( updatedData );
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle unserviceable address.
|
||||
if ( ! updatedData.shipping_options?.shippingOptions?.length ) {
|
||||
paymentDataRequestUpdate.error =
|
||||
this.unserviceableShippingAddressError();
|
||||
resolve( paymentDataRequestUpdate );
|
||||
return;
|
||||
} catch ( error ) {
|
||||
console.error( 'Error during onPaymentDataChanged:', error );
|
||||
reject( error );
|
||||
}
|
||||
|
||||
switch ( paymentData.callbackTrigger ) {
|
||||
case 'INITIALIZE':
|
||||
case 'SHIPPING_ADDRESS':
|
||||
paymentDataRequestUpdate.newShippingOptionParameters =
|
||||
updatedData.shipping_options;
|
||||
paymentDataRequestUpdate.newTransactionInfo =
|
||||
this.calculateNewTransactionInfo( updatedData );
|
||||
break;
|
||||
case 'SHIPPING_OPTION':
|
||||
paymentDataRequestUpdate.newTransactionInfo =
|
||||
this.calculateNewTransactionInfo( updatedData );
|
||||
break;
|
||||
}
|
||||
|
||||
resolve( paymentDataRequestUpdate );
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +1,76 @@
|
|||
import buttonModuleWatcher from '../../../ppcp-button/resources/js/modules/ButtonModuleWatcher';
|
||||
import GooglepayButton from './GooglepayButton';
|
||||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||
|
||||
class GooglepayManager {
|
||||
constructor( buttonConfig, ppcpConfig ) {
|
||||
this.buttonConfig = buttonConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
this.googlePayConfig = null;
|
||||
this.transactionInfo = null;
|
||||
this.contextHandler = null;
|
||||
|
||||
this.buttons = [];
|
||||
|
||||
buttonModuleWatcher.watchContextBootstrap( ( bootstrap ) => {
|
||||
buttonModuleWatcher.watchContextBootstrap( async ( bootstrap ) => {
|
||||
this.contextHandler = ContextHandlerFactory.create(
|
||||
bootstrap.context,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
bootstrap.handler
|
||||
);
|
||||
|
||||
const button = new GooglepayButton(
|
||||
bootstrap.context,
|
||||
bootstrap.handler,
|
||||
buttonConfig,
|
||||
ppcpConfig
|
||||
ppcpConfig,
|
||||
this.contextHandler
|
||||
);
|
||||
|
||||
this.buttons.push( button );
|
||||
|
||||
if ( this.googlePayConfig ) {
|
||||
button.init( this.googlePayConfig );
|
||||
// Initialize button only if googlePayConfig and transactionInfo are already fetched.
|
||||
if ( this.googlePayConfig && this.transactionInfo ) {
|
||||
button.init( this.googlePayConfig, this.transactionInfo );
|
||||
} else {
|
||||
await this.init();
|
||||
if ( this.googlePayConfig && this.transactionInfo ) {
|
||||
button.init( this.googlePayConfig, this.transactionInfo );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
init() {
|
||||
( async () => {
|
||||
// Gets GooglePay configuration of the PayPal merchant.
|
||||
this.googlePayConfig = await paypal.Googlepay().config();
|
||||
async init() {
|
||||
try {
|
||||
if ( ! this.googlePayConfig ) {
|
||||
// Gets GooglePay configuration of the PayPal merchant.
|
||||
this.googlePayConfig = await paypal.Googlepay().config();
|
||||
}
|
||||
|
||||
if ( ! this.transactionInfo ) {
|
||||
this.transactionInfo = await this.fetchTransactionInfo();
|
||||
}
|
||||
|
||||
for ( const button of this.buttons ) {
|
||||
button.init( this.googlePayConfig );
|
||||
button.init( this.googlePayConfig, this.transactionInfo );
|
||||
}
|
||||
} )();
|
||||
} catch ( error ) {
|
||||
console.error( 'Error during initialization:', error );
|
||||
}
|
||||
}
|
||||
|
||||
async fetchTransactionInfo() {
|
||||
try {
|
||||
if ( ! this.contextHandler ) {
|
||||
throw new Error( 'ContextHandler is not initialized' );
|
||||
}
|
||||
return await this.contextHandler.transactionInfo();
|
||||
} catch ( error ) {
|
||||
console.error( 'Error fetching transaction info:', error );
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
reinit() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import GooglepayButton from './GooglepayButton';
|
||||
import PreviewButton from '../../../ppcp-button/resources/js/modules/Renderer/PreviewButton';
|
||||
import PreviewButtonManager from '../../../ppcp-button/resources/js/modules/Renderer/PreviewButtonManager';
|
||||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||
|
||||
/**
|
||||
* Accessor that creates and returns a single PreviewButtonManager instance.
|
||||
|
@ -95,14 +96,22 @@ class GooglePayPreviewButton extends PreviewButton {
|
|||
}
|
||||
|
||||
createButton( buttonConfig ) {
|
||||
const contextHandler = ContextHandlerFactory.create(
|
||||
'preview',
|
||||
buttonConfig,
|
||||
this.ppcpConfig,
|
||||
null
|
||||
);
|
||||
|
||||
const button = new GooglepayButton(
|
||||
'preview',
|
||||
null,
|
||||
buttonConfig,
|
||||
this.ppcpConfig
|
||||
this.ppcpConfig,
|
||||
contextHandler
|
||||
);
|
||||
|
||||
button.init( this.apiConfig );
|
||||
button.init( this.apiConfig, null );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,23 +25,24 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
|||
return array(
|
||||
|
||||
// If GooglePay can be configured.
|
||||
'googlepay.eligible' => static function ( ContainerInterface $container ): bool {
|
||||
'googlepay.eligible' => static function ( ContainerInterface $container ): bool {
|
||||
$apm_applies = $container->get( 'googlepay.helpers.apm-applies' );
|
||||
assert( $apm_applies instanceof ApmApplies );
|
||||
|
||||
return $apm_applies->for_country_currency();
|
||||
return $apm_applies->for_country() && $apm_applies->for_currency();
|
||||
},
|
||||
|
||||
'googlepay.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies {
|
||||
'googlepay.helpers.apm-applies' => static function ( ContainerInterface $container ) : ApmApplies {
|
||||
return new ApmApplies(
|
||||
$container->get( 'googlepay.supported-country-currency-matrix' ),
|
||||
$container->get( 'googlepay.supported-countries' ),
|
||||
$container->get( 'googlepay.supported-currencies' ),
|
||||
$container->get( 'api.shop.currency' ),
|
||||
$container->get( 'api.shop.country' )
|
||||
);
|
||||
},
|
||||
|
||||
// If GooglePay is configured and onboarded.
|
||||
'googlepay.available' => static function ( ContainerInterface $container ): bool {
|
||||
'googlepay.available' => static function ( ContainerInterface $container ): bool {
|
||||
if ( apply_filters( 'woocommerce_paypal_payments_googlepay_validate_product_status', true ) ) {
|
||||
$status = $container->get( 'googlepay.helpers.apm-product-status' );
|
||||
assert( $status instanceof ApmProductStatus );
|
||||
|
@ -54,14 +55,14 @@ return array(
|
|||
},
|
||||
|
||||
// We assume it's a referral if we can check product status without API request failures.
|
||||
'googlepay.is_referral' => static function ( ContainerInterface $container ): bool {
|
||||
'googlepay.is_referral' => static function ( ContainerInterface $container ): bool {
|
||||
$status = $container->get( 'googlepay.helpers.apm-product-status' );
|
||||
assert( $status instanceof ApmProductStatus );
|
||||
|
||||
return ! $status->has_request_failure();
|
||||
},
|
||||
|
||||
'googlepay.availability_notice' => static function ( ContainerInterface $container ): AvailabilityNotice {
|
||||
'googlepay.availability_notice' => static function ( ContainerInterface $container ): AvailabilityNotice {
|
||||
return new AvailabilityNotice(
|
||||
$container->get( 'googlepay.helpers.apm-product-status' ),
|
||||
$container->get( 'wcgateway.is-wc-gateways-list-page' ),
|
||||
|
@ -69,7 +70,7 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'googlepay.helpers.apm-product-status' => SingletonDecorator::make(
|
||||
'googlepay.helpers.apm-product-status' => SingletonDecorator::make(
|
||||
static function( ContainerInterface $container ): ApmProductStatus {
|
||||
return new ApmProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
|
@ -81,86 +82,93 @@ return array(
|
|||
),
|
||||
|
||||
/**
|
||||
* The matrix which countries and currency combinations can be used for GooglePay.
|
||||
* The list of which countries can be used for GooglePay.
|
||||
*/
|
||||
'googlepay.supported-country-currency-matrix' => static function ( ContainerInterface $container ) : array {
|
||||
$default_currencies = array(
|
||||
'AUD',
|
||||
'BRL',
|
||||
'CAD',
|
||||
'CHF',
|
||||
'CZK',
|
||||
'DKK',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'HKD',
|
||||
'HUF',
|
||||
'ILS',
|
||||
'JPY',
|
||||
'MXN',
|
||||
'NOK',
|
||||
'NZD',
|
||||
'PHP',
|
||||
'PLN',
|
||||
'SEK',
|
||||
'SGD',
|
||||
'THB',
|
||||
'TWD',
|
||||
'USD',
|
||||
);
|
||||
|
||||
'googlepay.supported-countries' => static function ( ContainerInterface $container ) : array {
|
||||
/**
|
||||
* Returns which countries and currency combinations can be used for GooglePay.
|
||||
* Returns which countries can be used for GooglePay.
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_googlepay_supported_country_currency_matrix',
|
||||
'woocommerce_paypal_payments_googlepay_supported_countries',
|
||||
// phpcs:disable Squiz.Commenting.InlineComment
|
||||
array(
|
||||
'AU' => $default_currencies,
|
||||
'AT' => $default_currencies,
|
||||
'BE' => $default_currencies,
|
||||
'BG' => $default_currencies,
|
||||
'CA' => $default_currencies,
|
||||
'CY' => $default_currencies,
|
||||
'CZ' => $default_currencies,
|
||||
'DK' => $default_currencies,
|
||||
'EE' => $default_currencies,
|
||||
'FI' => $default_currencies,
|
||||
'FR' => $default_currencies,
|
||||
'DE' => $default_currencies,
|
||||
'GR' => $default_currencies,
|
||||
'HK' => $default_currencies,
|
||||
'HU' => $default_currencies,
|
||||
'IE' => $default_currencies,
|
||||
'IT' => $default_currencies,
|
||||
'LV' => $default_currencies,
|
||||
'LI' => $default_currencies,
|
||||
'LT' => $default_currencies,
|
||||
'LU' => $default_currencies,
|
||||
'MT' => $default_currencies,
|
||||
'NO' => $default_currencies,
|
||||
'NL' => $default_currencies,
|
||||
'PL' => $default_currencies,
|
||||
'PT' => $default_currencies,
|
||||
'RO' => $default_currencies,
|
||||
'SG' => $default_currencies,
|
||||
'SK' => $default_currencies,
|
||||
'SI' => $default_currencies,
|
||||
'ES' => $default_currencies,
|
||||
'SE' => $default_currencies,
|
||||
'GB' => $default_currencies,
|
||||
'US' => array(
|
||||
'AUD',
|
||||
'CAD',
|
||||
'EUR',
|
||||
'GBP',
|
||||
'JPY',
|
||||
'USD',
|
||||
),
|
||||
'AU', // Australia
|
||||
'AT', // Austria
|
||||
'BE', // Belgium
|
||||
'BG', // Bulgaria
|
||||
'CA', // Canada
|
||||
'CN', // China
|
||||
'CY', // Cyprus
|
||||
'CZ', // Czech Republic
|
||||
'DK', // Denmark
|
||||
'EE', // Estonia
|
||||
'FI', // Finland
|
||||
'FR', // France
|
||||
'DE', // Germany
|
||||
'GR', // Greece
|
||||
'HU', // Hungary
|
||||
'IE', // Ireland
|
||||
'IT', // Italy
|
||||
'LV', // Latvia
|
||||
'LI', // Liechtenstein
|
||||
'LT', // Lithuania
|
||||
'LU', // Luxembourg
|
||||
'MT', // Malta
|
||||
'NL', // Netherlands
|
||||
'NO', // Norway
|
||||
'PL', // Poland
|
||||
'PT', // Portugal
|
||||
'RO', // Romania
|
||||
'SK', // Slovakia
|
||||
'SI', // Slovenia
|
||||
'ES', // Spain
|
||||
'SE', // Sweden
|
||||
'US', // United States
|
||||
'GB', // United Kingdom
|
||||
)
|
||||
// phpcs:enable Squiz.Commenting.InlineComment
|
||||
);
|
||||
},
|
||||
|
||||
'googlepay.button' => static function ( ContainerInterface $container ): ButtonInterface {
|
||||
/**
|
||||
* The list of which currencies can be used for GooglePay.
|
||||
*/
|
||||
'googlepay.supported-currencies' => static function ( ContainerInterface $container ) : array {
|
||||
/**
|
||||
* Returns which currencies can be used for GooglePay.
|
||||
*/
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_googlepay_supported_currencies',
|
||||
// phpcs:disable Squiz.Commenting.InlineComment
|
||||
array(
|
||||
'AUD', // Australian Dollar
|
||||
'BRL', // Brazilian Real
|
||||
'CAD', // Canadian Dollar
|
||||
'CHF', // Swiss Franc
|
||||
'CZK', // Czech Koruna
|
||||
'DKK', // Danish Krone
|
||||
'EUR', // Euro
|
||||
'GBP', // British Pound Sterling
|
||||
'HKD', // Hong Kong Dollar
|
||||
'HUF', // Hungarian Forint
|
||||
'ILS', // Israeli New Shekel
|
||||
'JPY', // Japanese Yen
|
||||
'MXN', // Mexican Peso
|
||||
'NOK', // Norwegian Krone
|
||||
'NZD', // New Zealand Dollar
|
||||
'PHP', // Philippine Peso
|
||||
'PLN', // Polish Zloty
|
||||
'SEK', // Swedish Krona
|
||||
'SGD', // Singapore Dollar
|
||||
'THB', // Thai Baht
|
||||
'TWD', // New Taiwan Dollar
|
||||
'USD', // United States Dollar
|
||||
)
|
||||
// phpcs:enable Squiz.Commenting.InlineComment
|
||||
);
|
||||
},
|
||||
|
||||
'googlepay.button' => static function ( ContainerInterface $container ): ButtonInterface {
|
||||
return new Button(
|
||||
$container->get( 'googlepay.url' ),
|
||||
$container->get( 'googlepay.sdk_url' ),
|
||||
|
@ -174,7 +182,7 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'googlepay.blocks-payment-method' => static function ( ContainerInterface $container ): PaymentMethodTypeInterface {
|
||||
'googlepay.blocks-payment-method' => static function ( ContainerInterface $container ): PaymentMethodTypeInterface {
|
||||
return new BlocksPaymentMethod(
|
||||
'ppcp-googlepay',
|
||||
$container->get( 'googlepay.url' ),
|
||||
|
@ -184,7 +192,7 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'googlepay.url' => static function ( ContainerInterface $container ): string {
|
||||
'googlepay.url' => static function ( ContainerInterface $container ): string {
|
||||
$path = realpath( __FILE__ );
|
||||
if ( false === $path ) {
|
||||
return '';
|
||||
|
@ -195,26 +203,26 @@ return array(
|
|||
);
|
||||
},
|
||||
|
||||
'googlepay.sdk_url' => static function ( ContainerInterface $container ): string {
|
||||
'googlepay.sdk_url' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://pay.google.com/gp/p/js/pay.js';
|
||||
},
|
||||
|
||||
'googlepay.endpoint.update-payment-data' => static function ( ContainerInterface $container ): UpdatePaymentDataEndpoint {
|
||||
'googlepay.endpoint.update-payment-data' => static function ( ContainerInterface $container ): UpdatePaymentDataEndpoint {
|
||||
return new UpdatePaymentDataEndpoint(
|
||||
$container->get( 'button.request-data' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
|
||||
'googlepay.enable-url-sandbox' => static function ( ContainerInterface $container ): string {
|
||||
'googlepay.enable-url-sandbox' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://www.sandbox.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY';
|
||||
},
|
||||
|
||||
'googlepay.enable-url-live' => static function ( ContainerInterface $container ): string {
|
||||
'googlepay.enable-url-live' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://www.paypal.com/bizsignup/add-product?product=payment_methods&capabilities=GOOGLE_PAY';
|
||||
},
|
||||
|
||||
'googlepay.settings.connection.status-text' => static function ( ContainerInterface $container ): string {
|
||||
'googlepay.settings.connection.status-text' => static function ( ContainerInterface $container ): string {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
if ( $state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return '';
|
||||
|
@ -252,5 +260,14 @@ return array(
|
|||
esc_html( $button_text )
|
||||
);
|
||||
},
|
||||
|
||||
'googlepay.wc-gateway' => static function ( ContainerInterface $container ): GooglePayGateway {
|
||||
return new GooglePayGateway(
|
||||
$container->get( 'wcgateway.order-processor' ),
|
||||
$container->get( 'api.factory.paypal-checkout-url' ),
|
||||
$container->get( 'wcgateway.processor.refunds' ),
|
||||
$container->get( 'wcgateway.transaction-url-provider' ),
|
||||
$container->get( 'session.handler' ),
|
||||
$container->get( 'googlepay.url' )
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -13,7 +13,9 @@ use Exception;
|
|||
use Psr\Log\LoggerInterface;
|
||||
use WC_Countries;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Endpoint\UpdatePaymentDataEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\GooglePayGateway;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
|
@ -25,6 +27,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
*/
|
||||
class Button implements ButtonInterface {
|
||||
|
||||
use ContextTrait;
|
||||
|
||||
/**
|
||||
* The URL to the module.
|
||||
*
|
||||
|
@ -409,7 +413,7 @@ class Button implements ButtonInterface {
|
|||
*/
|
||||
public function script_data(): array {
|
||||
$shipping = array(
|
||||
'enabled' => $this->settings->has( 'googlepay_button_shipping_enabled' )
|
||||
'enabled' => $this->settings->has( 'googlepay_button_shipping_enabled' )
|
||||
? boolval( $this->settings->get( 'googlepay_button_shipping_enabled' ) )
|
||||
: false,
|
||||
'configured' => wc_shipping_enabled() && wc_get_shipping_method_count( false, true ) > 0,
|
||||
|
@ -421,19 +425,23 @@ class Button implements ButtonInterface {
|
|||
|
||||
$is_enabled = $this->settings->has( 'googlepay_button_enabled' ) && $this->settings->get( 'googlepay_button_enabled' );
|
||||
|
||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||
$is_wc_gateway_enabled = isset( $available_gateways[ GooglePayGateway::ID ] );
|
||||
|
||||
return array(
|
||||
'environment' => $this->environment->current_environment_is( Environment::SANDBOX ) ? 'TEST' : 'PRODUCTION',
|
||||
'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
|
||||
'is_enabled' => $is_enabled,
|
||||
'sdk_url' => $this->sdk_url,
|
||||
'button' => array(
|
||||
'environment' => $this->environment->current_environment_is( Environment::SANDBOX ) ? 'TEST' : 'PRODUCTION',
|
||||
'is_debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
|
||||
'is_enabled' => $is_enabled,
|
||||
'is_wc_gateway_enabled' => $is_wc_gateway_enabled,
|
||||
'sdk_url' => $this->sdk_url,
|
||||
'button' => array(
|
||||
'wrapper' => '#ppc-button-googlepay-container',
|
||||
'style' => $this->button_styles_for_context( 'cart' ), // For now use cart. Pass the context if necessary.
|
||||
'mini_cart_wrapper' => '#ppc-button-googlepay-container-minicart',
|
||||
'mini_cart_style' => $this->button_styles_for_context( 'mini-cart' ),
|
||||
),
|
||||
'shipping' => $shipping,
|
||||
'ajax' => array(
|
||||
'shipping' => $shipping,
|
||||
'ajax' => array(
|
||||
'update_payment_data' => array(
|
||||
'endpoint' => \WC_AJAX::get_endpoint( UpdatePaymentDataEndpoint::ENDPOINT ),
|
||||
'nonce' => wp_create_nonce( UpdatePaymentDataEndpoint::nonce() ),
|
||||
|
|
238
modules/ppcp-googlepay/src/GooglePayGateway.php
Normal file
238
modules/ppcp-googlepay/src/GooglePayGateway.php
Normal file
|
@ -0,0 +1,238 @@
|
|||
<?php
|
||||
/**
|
||||
* The Google Pay Payment Gateway
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Googlepay
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Googlepay;
|
||||
|
||||
use Exception;
|
||||
use WC_Order;
|
||||
use WC_Payment_Gateway;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\PayPalOrderMissingException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\Messages;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\ProcessPaymentTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
|
||||
/**
|
||||
* Class GooglePayGateway
|
||||
*/
|
||||
class GooglePayGateway extends WC_Payment_Gateway {
|
||||
use ProcessPaymentTrait;
|
||||
|
||||
const ID = 'ppcp-googlepay';
|
||||
|
||||
/**
|
||||
* The processor for orders.
|
||||
*
|
||||
* @var OrderProcessor
|
||||
*/
|
||||
protected $order_processor;
|
||||
|
||||
/**
|
||||
* The function return the PayPal checkout URL for the given order ID.
|
||||
*
|
||||
* @var callable(string):string
|
||||
*/
|
||||
private $paypal_checkout_url_factory;
|
||||
|
||||
/**
|
||||
* The Refund Processor.
|
||||
*
|
||||
* @var RefundProcessor
|
||||
*/
|
||||
private $refund_processor;
|
||||
|
||||
/**
|
||||
* Service able to provide transaction url for an order.
|
||||
*
|
||||
* @var TransactionUrlProvider
|
||||
*/
|
||||
protected $transaction_url_provider;
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
protected $session_handler;
|
||||
|
||||
/**
|
||||
* The URL to the module.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* GooglePayGateway constructor.
|
||||
*
|
||||
* @param OrderProcessor $order_processor The Order Processor.
|
||||
* @param callable(string):string $paypal_checkout_url_factory The function return the PayPal checkout URL for the given order ID.
|
||||
* @param RefundProcessor $refund_processor The Refund Processor.
|
||||
* @param TransactionUrlProvider $transaction_url_provider Service providing transaction view URL based on order.
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param string $module_url The URL to the module.
|
||||
*/
|
||||
public function __construct(
|
||||
OrderProcessor $order_processor,
|
||||
callable $paypal_checkout_url_factory,
|
||||
RefundProcessor $refund_processor,
|
||||
TransactionUrlProvider $transaction_url_provider,
|
||||
SessionHandler $session_handler,
|
||||
string $module_url
|
||||
) {
|
||||
$this->id = self::ID;
|
||||
|
||||
$this->method_title = __( 'Google Pay (via PayPal) ', 'woocommerce-paypal-payments' );
|
||||
$this->method_description = __( 'The separate payment gateway with the Google Pay button. If disabled, the button is included in the PayPal gateway.', 'woocommerce-paypal-payments' );
|
||||
|
||||
$this->title = $this->get_option( 'title', __( 'Google Pay', 'woocommerce-paypal-payments' ) );
|
||||
$this->description = $this->get_option( 'description', '' );
|
||||
|
||||
$this->module_url = $module_url;
|
||||
$this->icon = esc_url( $this->module_url ) . 'assets/images/googlepay.png';
|
||||
|
||||
$this->init_form_fields();
|
||||
$this->init_settings();
|
||||
$this->order_processor = $order_processor;
|
||||
$this->paypal_checkout_url_factory = $paypal_checkout_url_factory;
|
||||
$this->refund_processor = $refund_processor;
|
||||
$this->transaction_url_provider = $transaction_url_provider;
|
||||
$this->session_handler = $session_handler;
|
||||
|
||||
add_action(
|
||||
'woocommerce_update_options_payment_gateways_' . $this->id,
|
||||
array(
|
||||
$this,
|
||||
'process_admin_options',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the form fields.
|
||||
*/
|
||||
public function init_form_fields() {
|
||||
$this->form_fields = array(
|
||||
'enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'label' => __( 'Google Pay', 'woocommerce-paypal-payments' ),
|
||||
'default' => 'no',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Enable/Disable Google Pay payment gateway.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'title' => array(
|
||||
'title' => __( 'Title', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'default' => $this->title,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'description' => array(
|
||||
'title' => __( 'Description', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'default' => $this->description,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process payment for a WooCommerce order.
|
||||
*
|
||||
* @param int $order_id The WooCommerce order id.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function process_payment( $order_id ) {
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $wc_order, WC_Order::class ) ) {
|
||||
return $this->handle_payment_failure(
|
||||
null,
|
||||
new GatewayGenericException( new Exception( 'WC order was not found.' ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the WC_Order is paid through the approved webhook.
|
||||
*/
|
||||
//phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( isset( $_REQUEST['ppcp-resume-order'] ) && $wc_order->has_status( 'processing' ) ) {
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
}
|
||||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_before_process_order', $wc_order );
|
||||
|
||||
try {
|
||||
try {
|
||||
$this->order_processor->process( $wc_order );
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalOrderMissingException $exc ) {
|
||||
$order = $this->order_processor->create_order( $wc_order );
|
||||
|
||||
return array(
|
||||
'result' => 'success',
|
||||
'redirect' => ( $this->paypal_checkout_url_factory )( $order->id() ),
|
||||
);
|
||||
}
|
||||
} catch ( PayPalApiException $error ) {
|
||||
return $this->handle_payment_failure(
|
||||
$wc_order,
|
||||
new Exception(
|
||||
Messages::generic_payment_error_message() . ' ' . $error->getMessage(),
|
||||
$error->getCode(),
|
||||
$error
|
||||
)
|
||||
);
|
||||
} catch ( Exception $error ) {
|
||||
return $this->handle_payment_failure( $wc_order, $error );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process refund.
|
||||
*
|
||||
* If the gateway declares 'refunds' support, this will allow it to refund.
|
||||
* a passed in amount.
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param float $amount Refund amount.
|
||||
* @param string $reason Refund reason.
|
||||
* @return boolean True or false based on success, or a WP_Error object.
|
||||
*/
|
||||
public function process_refund( $order_id, $amount = null, $reason = '' ) {
|
||||
$order = wc_get_order( $order_id );
|
||||
if ( ! is_a( $order, \WC_Order::class ) ) {
|
||||
return false;
|
||||
}
|
||||
return $this->refund_processor->process( $order, (float) $amount, (string) $reason );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return transaction url for this gateway and given order.
|
||||
*
|
||||
* @param \WC_Order $order WC order to get transaction url by.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_transaction_url( $order ): string {
|
||||
$this->view_transaction_url = $this->transaction_url_provider->get_transaction_url_base( $order );
|
||||
|
||||
return parent::get_transaction_url( $order );
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\Googlepay;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
|
||||
use WC_Payment_Gateway;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\ButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\Endpoint\UpdatePaymentDataEndpoint;
|
||||
|
@ -159,6 +160,46 @@ class GooglepayModule implements ModuleInterface {
|
|||
},
|
||||
1
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'woocommerce_payment_gateways',
|
||||
/**
|
||||
* Param types removed to avoid third-party issues.
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
static function ( $methods ) use ( $c ): array {
|
||||
if ( ! is_array( $methods ) ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
if ( $settings->has( 'googlepay_button_enabled' ) && $settings->get( 'googlepay_button_enabled' ) ) {
|
||||
$googlepay_gateway = $c->get( 'googlepay.wc-gateway' );
|
||||
assert( $googlepay_gateway instanceof WC_Payment_Gateway );
|
||||
|
||||
$methods[] = $googlepay_gateway;
|
||||
}
|
||||
|
||||
return $methods;
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_review_order_after_submit',
|
||||
function () {
|
||||
echo '<div id="ppc-button-' . esc_attr( GooglePayGateway::ID ) . '"></div>';
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_pay_order_after_submit',
|
||||
function () {
|
||||
echo '<div id="ppc-button-' . esc_attr( GooglePayGateway::ID ) . '"></div>';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -16,11 +16,18 @@ namespace WooCommerce\PayPalCommerce\Googlepay\Helper;
|
|||
class ApmApplies {
|
||||
|
||||
/**
|
||||
* The matrix which countries and currency combinations can be used for GooglePay.
|
||||
* The list of which countries can be used for GooglePay.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $allowed_country_currency_matrix;
|
||||
private $allowed_countries;
|
||||
|
||||
/**
|
||||
* The list of which currencies can be used for GooglePay.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $allowed_currencies;
|
||||
|
||||
/**
|
||||
* 3-letter currency code of the shop.
|
||||
|
@ -39,30 +46,39 @@ class ApmApplies {
|
|||
/**
|
||||
* DccApplies constructor.
|
||||
*
|
||||
* @param array $allowed_country_currency_matrix The matrix which countries and currency combinations can be used for GooglePay.
|
||||
* @param array $allowed_countries The list of which countries can be used for GooglePay.
|
||||
* @param array $allowed_currencies The list of which currencies can be used for GooglePay.
|
||||
* @param string $currency 3-letter currency code of the shop.
|
||||
* @param string $country 2-letter country code of the shop.
|
||||
*/
|
||||
public function __construct(
|
||||
array $allowed_country_currency_matrix,
|
||||
array $allowed_countries,
|
||||
array $allowed_currencies,
|
||||
string $currency,
|
||||
string $country
|
||||
) {
|
||||
$this->allowed_country_currency_matrix = $allowed_country_currency_matrix;
|
||||
$this->currency = $currency;
|
||||
$this->country = $country;
|
||||
$this->allowed_countries = $allowed_countries;
|
||||
$this->allowed_currencies = $allowed_currencies;
|
||||
$this->currency = $currency;
|
||||
$this->country = $country;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether GooglePay can be used in the current country and the current currency used.
|
||||
* Returns whether GooglePay can be used in the current country used.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function for_country_currency(): bool {
|
||||
if ( ! in_array( $this->country, array_keys( $this->allowed_country_currency_matrix ), true ) ) {
|
||||
return false;
|
||||
}
|
||||
return in_array( $this->currency, $this->allowed_country_currency_matrix[ $this->country ], true );
|
||||
public function for_country(): bool {
|
||||
return in_array( $this->country, $this->allowed_countries, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether GooglePay can be used in the current currency used.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function for_currency(): bool {
|
||||
return in_array( $this->currency, $this->allowed_currencies, true );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -189,9 +189,8 @@ return array(
|
|||
$login_seller_sandbox = $container->get( 'api.endpoint.login-seller-sandbox' );
|
||||
$partner_referrals_data = $container->get( 'api.repository.partner-referrals-data' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
|
||||
$cache = new Cache( 'ppcp-paypal-bearer' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new LoginSellerEndpoint(
|
||||
$request_data,
|
||||
$login_seller_production,
|
||||
|
@ -199,7 +198,8 @@ return array(
|
|||
$partner_referrals_data,
|
||||
$settings,
|
||||
$cache,
|
||||
$logger
|
||||
$logger,
|
||||
new Cache( 'ppcp-client-credentials-cache' )
|
||||
);
|
||||
},
|
||||
'onboarding.endpoint.pui' => static function( ContainerInterface $container ) : UpdateSignupLinksEndpoint {
|
||||
|
|
|
@ -96,21 +96,21 @@ class OnboardingAssets {
|
|||
*/
|
||||
public function register(): bool {
|
||||
|
||||
$url = untrailingslashit( $this->module_url ) . '/assets/css/onboarding.css';
|
||||
wp_register_style(
|
||||
'ppcp-onboarding',
|
||||
$url,
|
||||
$this->module_url . '/assets/css/onboarding.css',
|
||||
array(),
|
||||
$this->version
|
||||
);
|
||||
$url = untrailingslashit( $this->module_url ) . '/assets/js/settings.js';
|
||||
|
||||
wp_register_script(
|
||||
'ppcp-settings',
|
||||
$url,
|
||||
$this->module_url . '/assets/js/settings.js',
|
||||
array(),
|
||||
$this->version,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'ppcp-settings',
|
||||
'PayPalCommerceSettings',
|
||||
|
@ -122,14 +122,14 @@ class OnboardingAssets {
|
|||
)
|
||||
);
|
||||
|
||||
$url = untrailingslashit( $this->module_url ) . '/assets/js/onboarding.js';
|
||||
wp_register_script(
|
||||
'ppcp-onboarding',
|
||||
$url,
|
||||
$this->module_url . '/assets/js/onboarding.js',
|
||||
array( 'jquery' ),
|
||||
$this->version,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script(
|
||||
'ppcp-onboarding',
|
||||
'PayPalCommerceGatewayOnboarding',
|
||||
|
@ -164,17 +164,22 @@ class OnboardingAssets {
|
|||
/**
|
||||
* Enqueues the necessary scripts.
|
||||
*
|
||||
* @return bool
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue(): bool {
|
||||
wp_enqueue_style( 'ppcp-onboarding' );
|
||||
wp_enqueue_script( 'ppcp-settings' );
|
||||
if ( ! $this->should_render_onboarding_script() ) {
|
||||
return false;
|
||||
public function enqueue(): void {
|
||||
// Do not enqueue anything when we are not on a PayPal Payments settings tab.
|
||||
if ( ! $this->page_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script( 'ppcp-onboarding' );
|
||||
return true;
|
||||
// Enqueue general assets for the plugin's settings page.
|
||||
wp_enqueue_script( 'ppcp-settings' );
|
||||
wp_enqueue_style( 'ppcp-onboarding' ); // File also contains general settings styles.
|
||||
|
||||
// Conditionally enqueue the onboarding script, when needed.
|
||||
if ( $this->should_render_onboarding_script() ) {
|
||||
wp_enqueue_script( 'ppcp-onboarding' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace WooCommerce\PayPalCommerce\Onboarding\Endpoint;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\LoginSeller;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PartnerReferralsData;
|
||||
|
@ -76,6 +78,13 @@ class LoginSellerEndpoint implements EndpointInterface {
|
|||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The client credentials cache.
|
||||
*
|
||||
* @var Cache
|
||||
*/
|
||||
private $client_credentials_cache;
|
||||
|
||||
/**
|
||||
* LoginSellerEndpoint constructor.
|
||||
*
|
||||
|
@ -86,6 +95,7 @@ class LoginSellerEndpoint implements EndpointInterface {
|
|||
* @param Settings $settings The Settings.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param Cache $client_credentials_cache The client credentials cache.
|
||||
*/
|
||||
public function __construct(
|
||||
RequestData $request_data,
|
||||
|
@ -94,16 +104,18 @@ class LoginSellerEndpoint implements EndpointInterface {
|
|||
PartnerReferralsData $partner_referrals_data,
|
||||
Settings $settings,
|
||||
Cache $cache,
|
||||
LoggerInterface $logger
|
||||
LoggerInterface $logger,
|
||||
Cache $client_credentials_cache
|
||||
) {
|
||||
|
||||
$this->request_data = $request_data;
|
||||
$this->login_seller_production = $login_seller_production;
|
||||
$this->login_seller_sandbox = $login_seller_sandbox;
|
||||
$this->partner_referrals_data = $partner_referrals_data;
|
||||
$this->settings = $settings;
|
||||
$this->cache = $cache;
|
||||
$this->logger = $logger;
|
||||
$this->request_data = $request_data;
|
||||
$this->login_seller_production = $login_seller_production;
|
||||
$this->login_seller_sandbox = $login_seller_sandbox;
|
||||
$this->partner_referrals_data = $partner_referrals_data;
|
||||
$this->settings = $settings;
|
||||
$this->cache = $cache;
|
||||
$this->logger = $logger;
|
||||
$this->client_credentials_cache = $client_credentials_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -175,6 +187,9 @@ class LoginSellerEndpoint implements EndpointInterface {
|
|||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
if ( $this->client_credentials_cache->has( SdkClientToken::CACHE_KEY ) ) {
|
||||
$this->client_credentials_cache->delete( SdkClientToken::CACHE_KEY );
|
||||
}
|
||||
|
||||
wp_schedule_single_event(
|
||||
time() + 5,
|
||||
|
|
|
@ -31,6 +31,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Endpoint\SubscriptionChangePaymentMethod;
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||
|
||||
/**
|
||||
* Class SavePaymentMethodsModule
|
||||
|
@ -84,7 +85,9 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
|||
add_filter(
|
||||
'woocommerce_paypal_payments_localized_script_data',
|
||||
function( array $localized_script_data ) use ( $c ) {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
$subscriptions_helper = $c->get( 'wc-subscriptions.helper' );
|
||||
assert( $subscriptions_helper instanceof SubscriptionHelper );
|
||||
if ( ! is_user_logged_in() && ! $subscriptions_helper->cart_contains_subscription() ) {
|
||||
return $localized_script_data;
|
||||
}
|
||||
|
||||
|
|
|
@ -133,6 +133,11 @@ $background-ident-color: #fbfbfb;
|
|||
}
|
||||
}
|
||||
|
||||
.ppcp-notice-list {
|
||||
list-style-type: disc;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
th, td {
|
||||
border-top: 1px solid $border-color;
|
||||
}
|
||||
|
|
|
@ -188,10 +188,6 @@ document.addEventListener( 'DOMContentLoaded', () => {
|
|||
}
|
||||
|
||||
function shouldDisableCardButton() {
|
||||
if ( currentTabId() === 'ppcp-card-button-gateway' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
PayPalCommerceGatewaySettings.is_acdc_enabled ||
|
||||
jQuery( '#ppcp-allow_card_button_gateway' ).is( ':checked' )
|
||||
|
@ -230,6 +226,14 @@ document.addEventListener( 'DOMContentLoaded', () => {
|
|||
}
|
||||
|
||||
if ( shouldDisableCardButton() ) {
|
||||
const standardCardButtonInput = document.querySelector(
|
||||
'#woocommerce_ppcp-card-button-gateway_enabled'
|
||||
);
|
||||
|
||||
if ( standardCardButtonInput ) {
|
||||
standardCardButtonInput.disabled = true;
|
||||
}
|
||||
|
||||
disabledSources = disabledSources.concat( 'card' );
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
|||
use WooCommerce\PayPalCommerce\Axo\Gateway\AxoGateway;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesDisclaimers;
|
||||
use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator;
|
||||
use WooCommerce\PayPalCommerce\Googlepay\GooglePayGateway;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
|
@ -196,6 +197,7 @@ return array(
|
|||
OXXOGateway::ID,
|
||||
Settings::PAY_LATER_TAB_ID,
|
||||
AxoGateway::ID,
|
||||
GooglePayGateway::ID,
|
||||
),
|
||||
true
|
||||
);
|
||||
|
@ -217,6 +219,7 @@ return array(
|
|||
CardButtonGateway::ID,
|
||||
Settings::PAY_LATER_TAB_ID,
|
||||
Settings::CONNECTION_TAB_ID,
|
||||
GooglePayGateway::ID,
|
||||
),
|
||||
true
|
||||
);
|
||||
|
@ -363,7 +366,8 @@ return array(
|
|||
$container->get( 'api.partner_merchant_id-production' ),
|
||||
$container->get( 'api.partner_merchant_id-sandbox' ),
|
||||
$container->get( 'api.endpoint.billing-agreements' ),
|
||||
$logger
|
||||
$logger,
|
||||
new Cache( 'ppcp-client-credentials-cache' )
|
||||
);
|
||||
},
|
||||
'wcgateway.order-processor' => static function ( ContainerInterface $container ): OrderProcessor {
|
||||
|
|
|
@ -106,6 +106,12 @@ class DisableGateways {
|
|||
return $methods;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$payment_method = wc_clean( wp_unslash( $_POST['payment_method'] ?? '' ) );
|
||||
if ( $payment_method && is_string( $payment_method ) ) {
|
||||
return array( $payment_method => $methods[ $payment_method ] );
|
||||
}
|
||||
|
||||
return array( PayPalGateway::ID => $methods[ PayPalGateway::ID ] );
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,10 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
|||
* Creates the admin message about the gateway being enabled without the PayPal gateway.
|
||||
*/
|
||||
class GatewayWithoutPayPalAdminNotice {
|
||||
private const NOTICE_OK = '';
|
||||
private const NOTICE_DISABLED_GATEWAY = 'disabled_gateway';
|
||||
private const NOTICE_DISABLED_LOCATION = 'disabled_location';
|
||||
private const NOTICE_OK = '';
|
||||
private const NOTICE_DISABLED_GATEWAY = 'disabled_gateway';
|
||||
private const NOTICE_DISABLED_LOCATION = 'disabled_location';
|
||||
private const NOTICE_DISABLED_CARD_BUTTON = 'disabled_card';
|
||||
|
||||
/**
|
||||
* The gateway ID.
|
||||
|
@ -99,6 +100,9 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
public function message(): ?Message {
|
||||
$notice_type = $this->check();
|
||||
|
||||
$url1 = '';
|
||||
$url2 = '';
|
||||
|
||||
switch ( $notice_type ) {
|
||||
case self::NOTICE_DISABLED_GATEWAY:
|
||||
/* translators: %1$s the gateway name, %2$s URL. */
|
||||
|
@ -114,6 +118,15 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
'woocommerce-paypal-payments'
|
||||
);
|
||||
break;
|
||||
case self::NOTICE_DISABLED_CARD_BUTTON:
|
||||
/* translators: %1$s Standard Card Button section URL, %2$s Advanced Card Processing section URL. */
|
||||
$text = __(
|
||||
'The <a href="%1$s">Standard Card Button</a> cannot be used while <a href="%2$s">Advanced Card Processing</a> is enabled.',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
$url1 = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-card-button-gateway' );
|
||||
$url2 = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway&ppcp-tab=ppcp-credit-card-gateway' );
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -130,6 +143,15 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
$name,
|
||||
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
|
||||
);
|
||||
|
||||
if ( $notice_type === self::NOTICE_DISABLED_CARD_BUTTON ) {
|
||||
$message = sprintf(
|
||||
$text,
|
||||
$url1,
|
||||
$url2
|
||||
);
|
||||
}
|
||||
|
||||
return new Message( $message, 'warning' );
|
||||
}
|
||||
|
||||
|
@ -160,6 +182,13 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
return self::NOTICE_DISABLED_LOCATION;
|
||||
}
|
||||
|
||||
$is_dcc_enabled = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ?? false;
|
||||
$is_card_button_allowed = $this->settings->has( 'allow_card_button_gateway' ) && $this->settings->get( 'allow_card_button_gateway' );
|
||||
|
||||
if ( $is_dcc_enabled && $is_card_button_allowed ) {
|
||||
return self::NOTICE_DISABLED_CARD_BUTTON;
|
||||
}
|
||||
|
||||
return self::NOTICE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
|||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\SdkClientToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\UserIdToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\BillingAgreementsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
|
@ -164,6 +166,13 @@ class SettingsListener {
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* The client credentials cache.
|
||||
*
|
||||
* @var Cache
|
||||
*/
|
||||
private $client_credentials_cache;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
|
@ -183,6 +192,7 @@ class SettingsListener {
|
|||
* @param string $partner_merchant_id_sandbox Partner merchant ID sandbox.
|
||||
* @param BillingAgreementsEndpoint $billing_agreements_endpoint Billing Agreements endpoint.
|
||||
* @param ?LoggerInterface $logger The logger.
|
||||
* @param Cache $client_credentials_cache The client credentials cache.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
|
@ -200,7 +210,8 @@ class SettingsListener {
|
|||
string $partner_merchant_id_production,
|
||||
string $partner_merchant_id_sandbox,
|
||||
BillingAgreementsEndpoint $billing_agreements_endpoint,
|
||||
LoggerInterface $logger = null
|
||||
LoggerInterface $logger = null,
|
||||
Cache $client_credentials_cache
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
|
@ -219,6 +230,7 @@ class SettingsListener {
|
|||
$this->partner_merchant_id_sandbox = $partner_merchant_id_sandbox;
|
||||
$this->billing_agreements_endpoint = $billing_agreements_endpoint;
|
||||
$this->logger = $logger ?: new NullLogger();
|
||||
$this->client_credentials_cache = $client_credentials_cache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -490,6 +502,9 @@ class SettingsListener {
|
|||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
if ( $this->client_credentials_cache->has( SdkClientToken::CACHE_KEY ) ) {
|
||||
$this->client_credentials_cache->delete( SdkClientToken::CACHE_KEY );
|
||||
}
|
||||
|
||||
if ( $this->pui_status_cache->has( PayUponInvoiceProductStatus::PUI_STATUS_CACHE_KEY ) ) {
|
||||
$this->pui_status_cache->delete( PayUponInvoiceProductStatus::PUI_STATUS_CACHE_KEY );
|
||||
|
|
|
@ -528,6 +528,14 @@ class WCGatewayModule implements ModuleInterface {
|
|||
return $methods;
|
||||
}
|
||||
|
||||
$is_dcc_enabled = $settings->has( 'dcc_enabled' ) && $settings->get( 'dcc_enabled' ) ?? false;
|
||||
$standard_card_button = get_option( 'woocommerce_ppcp-card-button-gateway_settings' );
|
||||
|
||||
if ( $is_dcc_enabled && isset( $standard_card_button['enabled'] ) ) {
|
||||
$standard_card_button['enabled'] = 'no';
|
||||
update_option( 'woocommerce_ppcp-card-button-gateway_settings', $standard_card_button );
|
||||
}
|
||||
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
assert( $dcc_applies instanceof DccApplies );
|
||||
|
||||
|
|
|
@ -416,7 +416,9 @@ class WcSubscriptionsModule implements ModuleInterface {
|
|||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
if ( $subscriptions_helper->plugin_is_active() ) {
|
||||
$subscriptions_mode = $settings->has( 'subscriptions_mode' ) ? $settings->get( 'subscriptions_mode' ) : '';
|
||||
|
||||
if ( 'disable_paypal_subscriptions' !== $subscriptions_mode && $subscriptions_helper->plugin_is_active() ) {
|
||||
$supports = array(
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
|
@ -442,7 +444,12 @@ class WcSubscriptionsModule implements ModuleInterface {
|
|||
$subscriptions_helper = $c->get( 'wc-subscriptions.helper' );
|
||||
assert( $subscriptions_helper instanceof SubscriptionHelper );
|
||||
|
||||
if ( $subscriptions_helper->plugin_is_active() ) {
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$vaulting_enabled = $settings->has( 'vault_enabled_dcc' ) && $settings->get( 'vault_enabled_dcc' );
|
||||
|
||||
if ( $vaulting_enabled && $subscriptions_helper->plugin_is_active() ) {
|
||||
$supports = array(
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
|
@ -467,7 +474,12 @@ class WcSubscriptionsModule implements ModuleInterface {
|
|||
$subscriptions_helper = $c->get( 'wc-subscriptions.helper' );
|
||||
assert( $subscriptions_helper instanceof SubscriptionHelper );
|
||||
|
||||
if ( $subscriptions_helper->plugin_is_active() ) {
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
$subscriptions_mode = $settings->has( 'subscriptions_mode' ) ? $settings->get( 'subscriptions_mode' ) : '';
|
||||
|
||||
if ( 'disable_paypal_subscriptions' !== $subscriptions_mode && $subscriptions_helper->plugin_is_active() ) {
|
||||
$supports = array(
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Webhooks;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "woocommerce-paypal-payments",
|
||||
"version": "2.8.2",
|
||||
"version": "2.8.3",
|
||||
"description": "WooCommerce PayPal Payments",
|
||||
"repository": "https://github.com/woocommerce/woocommerce-paypal-payments",
|
||||
"license": "GPL-2.0",
|
||||
|
|
23
readme.txt
23
readme.txt
|
@ -1,10 +1,10 @@
|
|||
=== WooCommerce PayPal Payments ===
|
||||
Contributors: woocommerce, automattic, inpsyde
|
||||
Contributors: woocommerce, automattic, syde
|
||||
Tags: woocommerce, paypal, payments, ecommerce, checkout, cart, pay later, apple pay, subscriptions, debit card, credit card, google pay
|
||||
Requires at least: 5.3
|
||||
Tested up to: 6.6
|
||||
Requires PHP: 7.2
|
||||
Stable tag: 2.8.2
|
||||
Stable tag: 2.8.3
|
||||
License: GPLv2
|
||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
|
@ -179,7 +179,24 @@ If you encounter issues with the PayPal buttons not appearing after an update, p
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 2.8.2 - xxxx-xx-xx =
|
||||
= 2.8.3 - 2024-08-12 =
|
||||
* Fix - Google Pay: Prevent field validation from being triggered on checkout page load #2474
|
||||
* Fix - Do not add tax info into order meta during order creation #2471
|
||||
* Fix - PayPal declares subscription support when for Subscription mode is set Disable PayPal for subscription #2425
|
||||
* Fix - PayPal js files loaded on non PayPal pages #2411
|
||||
* Fix - Google Pay: Fix the incorrect popup triggering #2414
|
||||
* Fix - Add tax configurator when programmatically creating WC orders #2431
|
||||
* Fix - Shipping callback compatibility with WC Name Your Price plugin #2402
|
||||
* Fix - Uncaught Error: Cannot use object of type ...\Settings as array in .../AbstractPaymentMethodType.php (3253) #2334
|
||||
* Fix - Prevent displaying smart button multiple times on variable product page #2420
|
||||
* Fix - Prevent enabling Standard Card Button when ACDC is enabled #2404
|
||||
* Fix - Use client credentials for user tokens #2491
|
||||
* Fix - Apple Pay: Fix the shipping callback #2492
|
||||
* Enhancement - Separate Google Pay button for Classic Checkout #2430
|
||||
* Enhancement - Add Apple Pay and Google Pay support for China, simplify country-currency matrix #2468
|
||||
* Enhancement - Add AMEX support for Advanced Card Processing in China #2469
|
||||
|
||||
= 2.8.2 - 2024-07-22 =
|
||||
* Fix - Sold individually checkbox automatically disabled after adding product to the cart more than once #2415
|
||||
* Fix - All products "Sold individually" when PayPal Subscriptions selected as Subscriptions Mode #2400
|
||||
* Fix - W3 Total Cache: Remove type from file parameter as sometimes null gets passed causing errors #2403
|
||||
|
|
|
@ -43,6 +43,7 @@ class SettingsListenerTest extends ModularTestCase
|
|||
$billing_agreement_endpoint = Mockery::mock(BillingAgreementsEndpoint::class);
|
||||
$subscription_helper = Mockery::mock(SubscriptionHelper::class);
|
||||
$logger = Mockery::mock(LoggerInterface::class);
|
||||
$client_credentials_cache = Mockery::mock(Cache::class);
|
||||
|
||||
$testee = new SettingsListener(
|
||||
$settings,
|
||||
|
@ -60,7 +61,8 @@ class SettingsListenerTest extends ModularTestCase
|
|||
'',
|
||||
'',
|
||||
$billing_agreement_endpoint,
|
||||
$logger
|
||||
$logger,
|
||||
$client_credentials_cache
|
||||
);
|
||||
|
||||
$_GET['section'] = PayPalGateway::ID;
|
||||
|
@ -94,6 +96,9 @@ class SettingsListenerTest extends ModularTestCase
|
|||
->andReturn(false);
|
||||
$dcc_status_cache->shouldReceive('has')
|
||||
->andReturn(false);
|
||||
$client_credentials_cache->shouldReceive('has')->andReturn(true);
|
||||
$client_credentials_cache->shouldReceive('delete');
|
||||
|
||||
|
||||
$testee->listen();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Plugin Name: WooCommerce PayPal Payments
|
||||
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
||||
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
||||
* Version: 2.8.2
|
||||
* Version: 2.8.3
|
||||
* Author: WooCommerce
|
||||
* Author URI: https://woocommerce.com/
|
||||
* License: GPL-2.0
|
||||
|
@ -26,7 +26,7 @@ define( 'PAYPAL_API_URL', 'https://api-m.paypal.com' );
|
|||
define( 'PAYPAL_URL', 'https://www.paypal.com' );
|
||||
define( 'PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com' );
|
||||
define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' );
|
||||
define( 'PAYPAL_INTEGRATION_DATE', '2024-07-17' );
|
||||
define( 'PAYPAL_INTEGRATION_DATE', '2024-08-07' );
|
||||
define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' );
|
||||
|
||||
! defined( 'CONNECT_WOO_CLIENT_ID' ) && define( 'CONNECT_WOO_CLIENT_ID', 'AcCAsWta_JTL__OfpjspNyH7c1GGHH332fLwonA5CwX4Y10mhybRZmHLA0GdRbwKwjQIhpDQy0pluX_P' );
|
||||
|
@ -223,6 +223,22 @@ define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' );
|
|||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'in_plugin_update_message-woocommerce-paypal-payments/woocommerce-paypal-payments.php',
|
||||
static function( array $plugin_data, \stdClass $new_data ) {
|
||||
if ( version_compare( $plugin_data['Version'], '3.0.0', '<' ) &&
|
||||
version_compare( $new_data->new_version, '3.0.0', '>=' ) ) {
|
||||
printf(
|
||||
'<br /><strong>%s</strong>: %s',
|
||||
esc_html__( 'Warning', 'woocommerce-paypal-payments' ),
|
||||
esc_html__( 'WooCommerce PayPal Payments version 3.0.0 contains significant changes that may impact your website. We strongly recommend reviewing the changes and testing the update on a staging site before updating it on your production environment.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
/**
|
||||
* Check if WooCommerce is active.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue