woocommerce-paypal-payments/modules/ppcp-button/src/Assets/class-smartbutton.php

947 lines
27 KiB
PHP
Raw Normal View History

2020-04-02 08:38:00 +03:00
<?php
2020-08-31 11:12:46 +03:00
/**
* Registers and configures the necessary Javascript for the button, credit messaging and DCC fields.
*
2020-09-11 14:11:10 +03:00
* @package WooCommerce\PayPalCommerce\Button\Assets
2020-08-31 11:12:46 +03:00
*/
2020-04-28 12:31:12 +03:00
2020-04-02 08:38:00 +03:00
declare(strict_types=1);
2020-09-11 14:11:10 +03:00
namespace WooCommerce\PayPalCommerce\Button\Assets;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\IdentityToken;
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayeeRepository;
use WooCommerce\PayPalCommerce\Button\Endpoint\ApproveOrderEndpoint;
use WooCommerce\PayPalCommerce\Button\Endpoint\ChangeCartEndpoint;
use WooCommerce\PayPalCommerce\Button\Endpoint\CreateOrderEndpoint;
use WooCommerce\PayPalCommerce\Button\Endpoint\DataClientIdEndpoint;
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
2020-09-11 14:11:10 +03:00
use WooCommerce\PayPalCommerce\Session\SessionHandler;
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
2020-04-02 08:38:00 +03:00
2020-08-31 11:12:46 +03:00
/**
* Class SmartButton
*/
2020-08-27 11:08:36 +03:00
class SmartButton implements SmartButtonInterface {
2020-08-31 11:12:46 +03:00
/**
* The URL to the module.
*
* @var string
*/
private $module_url;
/**
* The Session Handler.
*
* @var SessionHandler
*/
private $session_handler;
/**
* The settings.
*
* @var Settings
*/
2020-08-27 11:08:36 +03:00
private $settings;
2020-08-31 11:12:46 +03:00
/**
* The Payee Repository.
*
* @var PayeeRepository
*/
private $payee_repository;
/**
* The Identity Token.
*
* @var IdentityToken
*/
private $identity_token;
/**
* The Payer Factory.
*
* @var PayerFactory
*/
private $payer_factory;
/**
* The client ID.
*
* @var string
*/
private $client_id;
/**
* The Request Data.
*
* @var RequestData
*/
private $request_data;
/**
* The DCC Applies helper.
*
* @var DccApplies
*/
private $dcc_applies;
/**
* The Subscription Helper.
*
* @var SubscriptionHelper
*/
private $subscription_helper;
/**
* The Messages apply helper.
*
* @var MessagesApply
*/
private $messages_apply;
/**
* The environment object.
*
* @var Environment
*/
private $environment;
2020-08-31 11:12:46 +03:00
/**
* SmartButton constructor.
*
* @param string $module_url The URL to the module.
* @param SessionHandler $session_handler The Session Handler.
* @param Settings $settings The Settings.
* @param PayeeRepository $payee_repository The Payee Repository.
* @param IdentityToken $identity_token The Identity Token.
* @param PayerFactory $payer_factory The Payer factory.
* @param string $client_id The client ID.
* @param RequestData $request_data The Request Data helper.
* @param DccApplies $dcc_applies The DCC applies helper.
* @param SubscriptionHelper $subscription_helper The subscription helper.
* @param MessagesApply $messages_apply The Messages apply helper.
* @param Environment $environment The environment object.
2020-08-31 11:12:46 +03:00
*/
2020-08-27 11:08:36 +03:00
public function __construct(
2020-08-31 11:12:46 +03:00
string $module_url,
SessionHandler $session_handler,
2020-08-27 11:08:36 +03:00
Settings $settings,
2020-08-31 11:12:46 +03:00
PayeeRepository $payee_repository,
IdentityToken $identity_token,
PayerFactory $payer_factory,
string $client_id,
RequestData $request_data,
DccApplies $dcc_applies,
SubscriptionHelper $subscription_helper,
MessagesApply $messages_apply,
Environment $environment
2020-08-27 11:08:36 +03:00
) {
2020-08-31 11:12:46 +03:00
$this->module_url = $module_url;
$this->session_handler = $session_handler;
$this->settings = $settings;
$this->payee_repository = $payee_repository;
$this->identity_token = $identity_token;
$this->payer_factory = $payer_factory;
$this->client_id = $client_id;
$this->request_data = $request_data;
$this->dcc_applies = $dcc_applies;
$this->subscription_helper = $subscription_helper;
$this->messages_apply = $messages_apply;
$this->environment = $environment;
2020-08-27 11:08:36 +03:00
}
/**
2020-08-31 11:12:46 +03:00
* Registers the necessary action hooks to render the HTML depending on the settings.
*
2020-08-27 11:08:36 +03:00
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
2020-08-27 11:08:36 +03:00
*/
2020-08-31 11:12:46 +03:00
public function render_wrapper(): bool {
2020-08-27 11:08:36 +03:00
2020-08-31 11:12:46 +03:00
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
2020-08-27 11:08:36 +03:00
return false;
}
if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
2020-08-31 11:12:46 +03:00
$this->render_button_wrapper_registrar();
$this->render_message_wrapper_registrar();
2020-08-27 11:08:36 +03:00
}
if (
$this->settings->has( 'dcc_enabled' )
&& $this->settings->get( 'dcc_enabled' )
2020-08-31 11:12:46 +03:00
&& ! $this->session_handler->order()
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_review_order_after_submit',
array(
$this,
2020-08-31 11:12:46 +03:00
'dcc_renderer',
2020-08-27 11:08:36 +03:00
),
11
);
add_action(
'woocommerce_pay_order_after_submit',
array(
$this,
'dcc_renderer',
),
11
);
2020-08-27 11:08:36 +03:00
}
return true;
}
2020-08-31 11:12:46 +03:00
/**
* Registers the hooks to render the credit messaging HTML depending on the settings.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
2020-08-31 11:12:46 +03:00
*/
private function render_message_wrapper_registrar(): bool {
2020-08-27 11:08:36 +03:00
2020-08-31 11:12:46 +03:00
$not_enabled_on_cart = $this->settings->has( 'message_cart_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'message_cart_enabled' );
if (
is_cart()
2020-08-31 11:12:46 +03:00
&& ! $not_enabled_on_cart
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_proceed_to_checkout',
array(
$this,
2020-08-31 11:12:46 +03:00
'message_renderer',
2020-08-27 11:08:36 +03:00
),
19
);
}
2020-08-31 11:12:46 +03:00
$not_enabled_on_product_page = $this->settings->has( 'message_product_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'message_product_enabled' );
if (
( is_product() || wc_post_content_has_shortcode( 'product_page' ) )
2020-08-31 11:12:46 +03:00
&& ! $not_enabled_on_product_page
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_single_product_summary',
array(
$this,
2020-08-31 11:12:46 +03:00
'message_renderer',
2020-08-27 11:08:36 +03:00
),
30
);
}
2020-08-31 11:12:46 +03:00
$not_enabled_on_checkout = $this->settings->has( 'message_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'message_enabled' );
2020-08-31 11:12:46 +03:00
if ( ! $not_enabled_on_checkout ) {
2020-08-27 11:08:36 +03:00
add_action(
'woocommerce_review_order_after_submit',
array(
$this,
2020-08-31 11:12:46 +03:00
'message_renderer',
2020-08-27 11:08:36 +03:00
),
11
);
add_action(
'woocommerce_pay_order_after_submit',
array(
$this,
'message_renderer',
),
11
);
2020-08-27 11:08:36 +03:00
}
return true;
}
2020-08-31 11:12:46 +03:00
/**
* Registers the hooks where to render the button HTML according to the settings.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
2020-08-31 11:12:46 +03:00
*/
private function render_button_wrapper_registrar(): bool {
2020-08-27 11:08:36 +03:00
2020-08-31 11:12:46 +03:00
$not_enabled_on_cart = $this->settings->has( 'button_cart_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'button_cart_enabled' );
if (
is_cart()
2020-08-31 11:12:46 +03:00
&& ! $not_enabled_on_cart
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_proceed_to_checkout',
array(
$this,
2020-08-31 11:12:46 +03:00
'button_renderer',
2020-08-27 11:08:36 +03:00
),
20
);
}
2020-08-31 11:12:46 +03:00
$not_enabled_on_product_page = $this->settings->has( 'button_single_product_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'button_single_product_enabled' );
if (
( is_product() || wc_post_content_has_shortcode( 'product_page' ) )
2020-08-31 11:12:46 +03:00
&& ! $not_enabled_on_product_page
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_single_product_summary',
array(
$this,
2020-08-31 11:12:46 +03:00
'button_renderer',
2020-08-27 11:08:36 +03:00
),
31
);
}
2020-08-31 11:12:46 +03:00
$not_enabled_on_minicart = $this->settings->has( 'button_mini_cart_enabled' ) &&
2020-08-27 11:08:36 +03:00
! $this->settings->get( 'button_mini_cart_enabled' );
if (
2020-08-31 11:12:46 +03:00
! $not_enabled_on_minicart
2020-08-27 11:08:36 +03:00
) {
add_action(
'woocommerce_widget_shopping_cart_after_buttons',
static function () {
echo '<p
2020-08-21 10:38:48 +03:00
id="ppc-button-minicart"
class="woocommerce-mini-cart__buttons buttons"
></p>';
2020-08-27 11:08:36 +03:00
},
30
);
}
2020-08-31 11:12:46 +03:00
add_action( 'woocommerce_review_order_after_submit', array( $this, 'button_renderer' ), 10 );
add_action( 'woocommerce_pay_order_after_submit', array( $this, 'button_renderer' ), 10 );
2020-08-27 11:08:36 +03:00
return true;
}
2020-08-31 11:12:46 +03:00
/**
* Enqueues the script.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
2020-08-31 11:12:46 +03:00
*/
2020-08-27 11:08:36 +03:00
public function enqueue(): bool {
2020-08-31 11:12:46 +03:00
$buttons_enabled = $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' );
if ( ! is_checkout() && ! $buttons_enabled ) {
2020-08-27 11:08:36 +03:00
return false;
}
2020-08-31 11:12:46 +03:00
if ( ! $this->can_save_vault_token() && $this->has_subscriptions() ) {
2020-08-27 11:08:36 +03:00
return false;
}
2020-09-03 11:48:25 +03:00
$load_script = false;
if ( is_checkout() && $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) ) {
$load_script = true;
}
if ( $this->load_button_component() ) {
$load_script = true;
}
if ( in_array( $this->context(), array( 'pay-now', 'checkout' ), true ) && $this->can_render_dcc() ) {
wp_enqueue_style(
'ppcp-hosted-fields',
$this->module_url . '/assets/css/hosted-fields.css',
array(),
1
);
}
2020-09-03 11:48:25 +03:00
if ( $load_script ) {
wp_enqueue_script(
'ppcp-smart-button',
$this->module_url . '/assets/js/button.js',
array( 'jquery' ),
1,
true
);
wp_localize_script(
'ppcp-smart-button',
'PayPalCommerceGateway',
$this->localize_script()
);
}
2020-08-27 11:08:36 +03:00
return true;
}
2020-08-31 11:12:46 +03:00
/**
* Renders the HTML for the buttons.
*/
public function button_renderer() {
2020-08-27 11:08:36 +03:00
$product = wc_get_product();
if (
! is_checkout() && is_a( $product, \WC_Product::class )
&& (
$product->is_type( array( 'external', 'grouped' ) )
|| ! $product->is_in_stock()
)
) {
return;
}
echo '<div id="ppc-button"></div>';
}
2020-08-31 11:12:46 +03:00
/**
* Renders the HTML for the credit messaging.
*/
public function message_renderer() {
2020-08-27 11:08:36 +03:00
echo '<div id="ppcp-messages"></div>';
}
2020-08-19 05:19:29 +03:00
2020-08-31 11:12:46 +03:00
/**
* The values for the credit messaging.
*
* @return array
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
2020-08-31 11:12:46 +03:00
*/
private function message_values(): array {
2020-08-27 11:08:36 +03:00
if (
$this->settings->has( 'disable_funding' )
&& in_array( 'credit', (array) $this->settings->get( 'disable_funding' ), true )
) {
return array();
}
2020-08-31 11:12:46 +03:00
$placement = 'product';
$product = wc_get_product();
$amount = ( is_a( $product, \WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
$layout = $this->settings->has( 'message_product_layout' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_layout' ) : 'text';
2020-08-31 11:12:46 +03:00
$logo_type = $this->settings->has( 'message_product_logo' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_logo' ) : 'primary';
2020-08-31 11:12:46 +03:00
$logo_position = $this->settings->has( 'message_product_position' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_position' ) : 'left';
2020-08-31 11:12:46 +03:00
$text_color = $this->settings->has( 'message_product_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_color' ) : 'black';
2020-08-31 11:12:46 +03:00
$style_color = $this->settings->has( 'message_product_flex_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_flex_color' ) : 'blue';
2020-08-31 11:12:46 +03:00
$ratio = $this->settings->has( 'message_product_flex_ratio' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_product_flex_ratio' ) : '1x1';
2020-08-31 11:12:46 +03:00
$should_show = $this->settings->has( 'message_product_enabled' )
2020-08-27 11:08:36 +03:00
&& $this->settings->get( 'message_product_enabled' );
if ( is_checkout() ) {
2020-08-31 11:12:46 +03:00
$placement = 'payment';
$amount = WC()->cart->get_total( 'raw' );
$layout = $this->settings->has( 'message_layout' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_layout' ) : 'text';
2020-08-31 11:12:46 +03:00
$logo_type = $this->settings->has( 'message_logo' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_logo' ) : 'primary';
2020-08-31 11:12:46 +03:00
$logo_position = $this->settings->has( 'message_position' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_position' ) : 'left';
2020-08-31 11:12:46 +03:00
$text_color = $this->settings->has( 'message_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_color' ) : 'black';
2020-08-31 11:12:46 +03:00
$style_color = $this->settings->has( 'message_flex_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_flex_color' ) : 'blue';
2020-08-31 11:12:46 +03:00
$ratio = $this->settings->has( 'message_flex_ratio' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_flex_ratio' ) : '1x1';
2020-08-31 11:12:46 +03:00
$should_show = $this->settings->has( 'message_enabled' )
2020-08-27 11:08:36 +03:00
&& $this->settings->get( 'message_enabled' );
}
if ( is_cart() ) {
2020-08-31 11:12:46 +03:00
$placement = 'cart';
$amount = WC()->cart->get_total( 'raw' );
$layout = $this->settings->has( 'message_cart_layout' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_layout' ) : 'text';
2020-08-31 11:12:46 +03:00
$logo_type = $this->settings->has( 'message_cart_logo' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_logo' ) : 'primary';
2020-08-31 11:12:46 +03:00
$logo_position = $this->settings->has( 'message_cart_position' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_position' ) : 'left';
2020-08-31 11:12:46 +03:00
$text_color = $this->settings->has( 'message_cart_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_color' ) : 'black';
2020-08-31 11:12:46 +03:00
$style_color = $this->settings->has( 'message_cart_flex_color' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_flex_color' ) : 'blue';
2020-08-31 11:12:46 +03:00
$ratio = $this->settings->has( 'message_cart_flex_ratio' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'message_cart_flex_ratio' ) : '1x1';
2020-08-31 11:12:46 +03:00
$should_show = $this->settings->has( 'message_cart_enabled' )
2020-08-27 11:08:36 +03:00
&& $this->settings->get( 'message_cart_enabled' );
}
2020-08-31 11:12:46 +03:00
if ( ! $should_show ) {
2020-08-27 11:08:36 +03:00
return array();
}
$values = array(
'wrapper' => '#ppcp-messages',
'amount' => $amount,
'placement' => $placement,
'style' => array(
'layout' => $layout,
'logo' => array(
2020-08-31 11:12:46 +03:00
'type' => $logo_type,
'position' => $logo_position,
2020-08-27 11:08:36 +03:00
),
'text' => array(
2020-08-31 11:12:46 +03:00
'color' => $text_color,
2020-08-27 11:08:36 +03:00
),
2020-08-31 11:12:46 +03:00
'color' => $style_color,
2020-08-27 11:08:36 +03:00
'ratio' => $ratio,
),
);
return $values;
}
2020-08-19 05:19:29 +03:00
2020-08-31 11:12:46 +03:00
/**
* Whether DCC fields can be rendered.
2020-08-31 11:12:46 +03:00
*
* @return bool
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting was not found.
*/
private function can_render_dcc() : bool {
$can_render = $this->settings->has( 'dcc_enabled' ) && $this->settings->get( 'dcc_enabled' ) && $this->settings->has( 'client_id' ) && $this->settings->get( 'client_id' ) && $this->dcc_applies->for_country_currency();
return $can_render;
}
/**
* Renders the HTML for the DCC fields.
2020-08-31 11:12:46 +03:00
*/
public function dcc_renderer() {
$id = 'ppcp-hosted-fields';
if ( ! $this->can_render_dcc() ) {
2020-08-27 11:08:36 +03:00
return;
}
$save_card = $this->can_save_credit_card() ? sprintf(
2020-08-27 11:08:36 +03:00
'<div>
<label for="ppcp-vault-%1$s">%2$s</label>
<input
type="checkbox"
id="ppcp-vault-%1$s"
class="ppcp-credit-card-vault"
name="vault"
>
</div>',
2020-08-27 11:08:36 +03:00
esc_attr( $id ),
esc_html__( 'Save your card', 'woocommerce-paypal-payments' )
2020-08-27 11:08:36 +03:00
) : '';
$label = 'checkout' === $this->context() ? __( 'Place order', 'woocommerce-paypal-payments' ) : __( 'Pay for order', 'woocommerce-paypal-payments' );
2020-08-27 11:08:36 +03:00
printf(
'<div id="%1$s" style="display:none;">
<button class="button alt">%3$s</button>
%2$s
</div><div id="payments-sdk__contingency-lightbox"></div><style id="ppcp-hide-dcc">.payment_method_ppcp-credit-card-gateway {display:none;}</style>',
2020-08-27 11:08:36 +03:00
esc_attr( $id ),
//phpcs:ignore
2020-08-31 11:12:46 +03:00
$save_card,
esc_html( $label )
2020-08-27 11:08:36 +03:00
);
}
2020-08-31 11:12:46 +03:00
/**
* Whether we can store vault tokens or not.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasnt been found.
2020-08-31 11:12:46 +03:00
*/
public function can_save_vault_token(): bool {
2020-08-27 11:08:36 +03:00
if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
return false;
}
if ( ! $this->settings->has( 'vault_enabled' ) || ! $this->settings->get( 'vault_enabled' ) ) {
return false;
}
return is_user_logged_in();
}
private function can_save_credit_card() {
if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
return false;
}
if ( ! $this->settings->has( 'dcc_save_card' ) || ! $this->settings->get( 'dcc_save_card' ) ) {
return false;
}
return is_user_logged_in();
}
2020-08-31 11:12:46 +03:00
/**
* Whether we need to initialize the script to enable tokenization for subscriptions or not.
*
* @return bool
*/
private function has_subscriptions(): bool {
if ( ! $this->subscription_helper->accept_only_automatic_payment_gateways() ) {
2020-08-27 11:08:36 +03:00
return false;
}
if ( is_product() ) {
2020-08-31 11:12:46 +03:00
return $this->subscription_helper->current_product_is_subscription();
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
return $this->subscription_helper->cart_contains_subscription();
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
/**
* The localized data for the smart button.
*
* @return array
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting hasn't been found.
2020-08-31 11:12:46 +03:00
*/
private function localize_script(): array {
global $wp;
2020-08-31 11:12:46 +03:00
$this->request_data->enqueue_nonce_fix();
2020-08-27 11:08:36 +03:00
$localize = array(
'script_attributes' => $this->attributes(),
'data_client_id' => array(
'set_attribute' => ( is_checkout() && $this->dcc_is_enabled() )
2020-08-31 11:12:46 +03:00
|| $this->can_save_vault_token(),
'save_paypal_account' => $this->save_paypal_account(),
'endpoint' => home_url( \WC_AJAX::get_endpoint( DataClientIdEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( DataClientIdEndpoint::nonce() ),
'user' => get_current_user_id(),
2020-08-27 11:08:36 +03:00
),
'redirect' => wc_get_checkout_url(),
'context' => $this->context(),
'ajax' => array(
'change_cart' => array(
'endpoint' => home_url( \WC_AJAX::get_endpoint( ChangeCartEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( ChangeCartEndpoint::nonce() ),
),
'create_order' => array(
'endpoint' => home_url( \WC_AJAX::get_endpoint( CreateOrderEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( CreateOrderEndpoint::nonce() ),
),
'approve_order' => array(
'endpoint' => home_url( \WC_AJAX::get_endpoint( ApproveOrderEndpoint::ENDPOINT ) ),
'nonce' => wp_create_nonce( ApproveOrderEndpoint::nonce() ),
),
),
2020-08-31 11:12:46 +03:00
'enforce_vault' => $this->has_subscriptions(),
'bn_codes' => $this->bn_codes(),
2020-08-27 11:08:36 +03:00
'payer' => $this->payerData(),
'button' => array(
'wrapper' => '#ppc-button',
'mini_cart_wrapper' => '#ppc-button-minicart',
'cancel_wrapper' => '#ppcp-cancel',
'url' => $this->url(),
'mini_cart_style' => array(
2020-08-31 11:12:46 +03:00
'layout' => $this->style_for_context( 'layout', 'mini-cart' ),
'color' => $this->style_for_context( 'color', 'mini-cart' ),
'shape' => $this->style_for_context( 'shape', 'mini-cart' ),
'label' => $this->style_for_context( 'label', 'mini-cart' ),
'tagline' => $this->style_for_context( 'tagline', 'mini-cart' ),
2020-08-27 11:08:36 +03:00
),
'style' => array(
2020-08-31 11:12:46 +03:00
'layout' => $this->style_for_context( 'layout', $this->context() ),
'color' => $this->style_for_context( 'color', $this->context() ),
'shape' => $this->style_for_context( 'shape', $this->context() ),
'label' => $this->style_for_context( 'label', $this->context() ),
'tagline' => $this->style_for_context( 'tagline', $this->context() ),
2020-08-27 11:08:36 +03:00
),
),
'hosted_fields' => array(
'wrapper' => '#ppcp-hosted-fields',
'mini_cart_wrapper' => '#ppcp-hosted-fields-mini-cart',
'labels' => array(
'credit_card_number' => '',
'cvv' => '',
'mm_yyyy' => __( 'MM/YYYY', 'woocommerce-paypal-payments' ),
2020-08-27 11:08:36 +03:00
'fields_not_valid' => __(
'Unfortunatly, your credit card details are not valid.',
'woocommerce-paypal-payments'
2020-08-27 11:08:36 +03:00
),
'card_not_supported' => __(
'Unfortunatly, we do not support your credit card.',
'woocommerce-paypal-payments'
),
2020-08-27 11:08:36 +03:00
),
'valid_cards' => $this->dcc_applies->valid_cards(),
2020-08-27 11:08:36 +03:00
),
2020-08-31 11:12:46 +03:00
'messages' => $this->message_values(),
2020-08-27 11:08:36 +03:00
'labels' => array(
'error' => array(
'generic' => __(
'Something went wrong. Please try again or choose another payment source.',
'woocommerce-paypal-payments'
2020-08-27 11:08:36 +03:00
),
),
),
'order_id' => 'pay-now' === $this->context() ? absint( $wp->query_vars['order-pay'] ) : 0,
2020-08-27 11:08:36 +03:00
);
2020-08-31 11:12:46 +03:00
if ( $this->style_for_context( 'layout', 'mini-cart' ) !== 'horizontal' ) {
2020-08-27 11:08:36 +03:00
unset( $localize['button']['mini_cart_style']['tagline'] );
}
2020-08-31 11:12:46 +03:00
if ( $this->style_for_context( 'layout', $this->context() ) !== 'horizontal' ) {
2020-08-27 11:08:36 +03:00
unset( $localize['button']['style']['tagline'] );
}
2020-08-31 11:12:46 +03:00
$this->request_data->dequeue_nonce_fix();
2020-08-27 11:08:36 +03:00
return $localize;
}
2020-04-13 09:07:20 +03:00
2020-08-31 11:12:46 +03:00
/**
* If we can find the payer data for a current customer, we will return it.
*
* @return array|null
*/
2020-09-11 13:38:02 +03:00
private function payerData() {
2020-08-27 11:08:36 +03:00
$customer = WC()->customer;
if ( ! is_user_logged_in() || ! is_a( $customer, \WC_Customer::class ) ) {
return null;
}
2020-09-01 09:00:45 +03:00
return $this->payer_factory->from_customer( $customer )->to_array();
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
/**
* The JavaScript SDK url to load.
*
* @return string
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
2020-08-31 11:12:46 +03:00
*/
2020-08-27 11:08:36 +03:00
private function url(): string {
$params = array(
2020-08-31 11:12:46 +03:00
'client-id' => $this->client_id,
2020-08-27 11:08:36 +03:00
'currency' => get_woocommerce_currency(),
'locale' => get_user_locale(),
2020-10-08 07:28:43 +03:00
'integration-date' => PAYPAL_INTEGRATION_DATE,
2020-08-27 11:08:36 +03:00
'components' => implode( ',', $this->components() ),
2020-10-07 08:42:13 +03:00
'vault' => $this->can_save_vault_token() ?
2020-08-27 11:08:36 +03:00
'true' : 'false',
'commit' => is_checkout() ? 'true' : 'false',
'intent' => ( $this->settings->has( 'intent' ) ) ?
$this->settings->get( 'intent' ) : 'capture',
);
if (
$this->environment->current_environment_is( Environment::SANDBOX )
&& defined( 'WP_DEBUG' ) && \WP_DEBUG && is_user_logged_in()
2020-08-27 11:08:36 +03:00
&& WC()->customer && WC()->customer->get_billing_country()
&& 2 === strlen( WC()->customer->get_billing_country() )
2020-08-27 11:08:36 +03:00
) {
$params['buyer-country'] = WC()->customer->get_billing_country();
}
2020-08-31 11:12:46 +03:00
$payee = $this->payee_repository->payee();
2020-09-01 09:00:45 +03:00
if ( $payee->merchant_id() ) {
$params['merchant-id'] = $payee->merchant_id();
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
$disable_funding = $this->settings->has( 'disable_funding' ) ?
2020-08-27 11:08:36 +03:00
$this->settings->get( 'disable_funding' ) : array();
2020-08-31 11:12:46 +03:00
$disable_funding[] = 'venmo';
2020-08-27 11:08:36 +03:00
if ( ! is_checkout() ) {
2020-08-31 11:12:46 +03:00
$disable_funding[] = 'card';
2020-08-27 11:08:36 +03:00
}
/**
* Disable card for UK.
*/
$region = wc_get_base_location();
$country = $region['country'];
if ( 'GB' === $country ) {
$disable_funding[] = 'credit';
}
2020-08-31 11:12:46 +03:00
$params['disable-funding'] = implode( ',', array_unique( $disable_funding ) );
2020-09-18 12:02:27 +03:00
$smart_button_url = add_query_arg( $params, 'https://www.paypal.com/sdk/js' );
2020-08-31 11:12:46 +03:00
return $smart_button_url;
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
/**
* The attributes we need to load for the JS SDK.
*
* @return array
*/
2020-08-27 11:08:36 +03:00
private function attributes(): array {
return array(
2020-08-31 11:12:46 +03:00
'data-partner-attribution-id' => $this->bn_code_for_context( $this->context() ),
2020-08-27 11:08:36 +03:00
);
}
/**
2020-08-31 11:12:46 +03:00
* What BN Code to use in a given context.
*
* @param string $context The context.
2020-08-27 11:08:36 +03:00
* @return string
*/
2020-08-31 11:12:46 +03:00
private function bn_code_for_context( string $context ): string {
2020-08-27 11:08:36 +03:00
2020-08-31 11:12:46 +03:00
$codes = $this->bn_codes();
2020-08-27 11:08:36 +03:00
return ( isset( $codes[ $context ] ) ) ? $codes[ $context ] : '';
}
/**
2020-08-31 11:12:46 +03:00
* BN Codes to use.
2020-08-27 11:08:36 +03:00
*
* @return array
*/
2020-08-31 11:12:46 +03:00
private function bn_codes(): array {
2020-08-27 11:08:36 +03:00
return array(
'checkout' => 'Woo_PPCP',
'cart' => 'Woo_PPCP',
'mini-cart' => 'Woo_PPCP',
'product' => 'Woo_PPCP',
);
}
2020-08-31 11:12:46 +03:00
/**
* The JS SKD components we need to load.
*
* @return array
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting was not found.
2020-08-31 11:12:46 +03:00
*/
2020-08-27 11:08:36 +03:00
private function components(): array {
$components = array();
2020-09-03 11:48:25 +03:00
if ( $this->load_button_component() ) {
$components[] = 'buttons';
}
if ( $this->messages_apply->for_country() ) {
$components[] = 'messages';
}
if ( $this->dcc_is_enabled() ) {
$components[] = 'hosted-fields';
}
return $components;
}
/**
* Determines whether the button component should be loaded.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting has not been found.
2020-09-03 11:48:25 +03:00
*/
private function load_button_component() : bool {
$load_buttons = false;
if (
$this->context() === 'checkout'
&& $this->settings->has( 'button_enabled' )
&& $this->settings->get( 'button_enabled' )
) {
$load_buttons = true;
}
if (
$this->context() === 'product'
&& $this->settings->has( 'button_product_enabled' )
&& $this->settings->get( 'button_product_enabled' )
) {
$load_buttons = true;
}
if (
2020-09-03 11:48:25 +03:00
$this->settings->has( 'button_mini-cart_enabled' )
&& $this->settings->get( 'button_mini-cart_enabled' )
) {
$load_buttons = true;
}
if (
$this->context() === 'cart'
&& $this->settings->has( 'button_cart_enabled' )
&& $this->settings->get( 'button_cart_enabled' )
) {
$load_buttons = true;
}
2021-01-05 11:35:47 +01:00
if ( $this->context() === 'pay-now' ) {
$load_buttons = true;
}
2020-09-03 11:48:25 +03:00
return $load_buttons;
2020-08-27 11:08:36 +03:00
}
2020-08-31 11:12:46 +03:00
/**
* The current context.
*
* @return string
*/
2020-08-27 11:08:36 +03:00
private function context(): string {
$context = 'mini-cart';
if ( is_product() || wc_post_content_has_shortcode( 'product_page' ) ) {
$context = 'product';
}
if ( is_cart() ) {
$context = 'cart';
}
2020-08-31 11:12:46 +03:00
if ( is_checkout() && ! $this->session_handler->order() ) {
2020-08-27 11:08:36 +03:00
$context = 'checkout';
}
if ( is_checkout_pay_page() ) {
$context = 'pay-now';
}
2020-08-27 11:08:36 +03:00
return $context;
}
2020-08-31 11:12:46 +03:00
/**
* Whether DCC is enabled or not.
*
* @return bool
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException If a setting has not been found.
2020-08-31 11:12:46 +03:00
*/
private function dcc_is_enabled(): bool {
if ( ! is_checkout() ) {
return false;
}
2020-09-01 09:00:45 +03:00
if ( ! $this->dcc_applies->for_country_currency() ) {
2020-08-27 11:08:36 +03:00
return false;
}
$keys = array(
'client_id',
'client_secret',
'dcc_enabled',
2020-08-27 11:08:36 +03:00
);
foreach ( $keys as $key ) {
if ( ! $this->settings->has( $key ) || ! $this->settings->get( $key ) ) {
return false;
2020-08-27 11:08:36 +03:00
}
}
return true;
2020-08-27 11:08:36 +03:00
}
private function save_paypal_account(): bool {
if ( ! $this->settings->has( 'save_paypal_account' ) || ! $this->settings->get( 'save_paypal_account' ) ) {
return false;
}
return true;
}
2020-08-31 11:12:46 +03:00
/**
* Determines the style for a given indicator in a given context.
*
* @param string $style The style.
* @param string $context The context.
*
* @return string
2020-09-11 14:11:10 +03:00
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting hasn't been found.
2020-08-31 11:12:46 +03:00
*/
private function style_for_context( string $style, string $context ): string {
2020-08-27 11:08:36 +03:00
$defaults = array(
'layout' => 'vertical',
'size' => 'responsive',
'color' => 'gold',
'shape' => 'pill',
'label' => 'paypal',
'tagline' => true,
);
$value = isset( $defaults[ $style ] ) ?
$defaults[ $style ] : '';
$value = $this->settings->has( 'button_' . $style ) ?
$this->settings->get( 'button_' . $style ) : $value;
$value = $this->settings->has( 'button_' . $context . '_' . $style ) ?
$this->settings->get( 'button_' . $context . '_' . $style ) : $value;
if ( is_bool( $value ) ) {
$value = $value ? 'true' : 'false';
}
2020-09-02 12:47:53 +03:00
return (string) $value;
2020-08-27 11:08:36 +03:00
}
2020-04-06 11:16:18 +03:00
}