mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 09:08:09 +08:00
Merge remote-tracking branch 'origin/trunk' into modularity-module-migration
# Conflicts: # modules/ppcp-admin-notices/src/AdminNotices.php # modules/ppcp-save-payment-methods/src/SavePaymentMethodsModule.php # modules/ppcp-wc-gateway/src/WCGatewayModule.php # modules/ppcp-wc-subscriptions/src/WcSubscriptionsModule.php # tests/PHPUnit/WcSubscriptions/RenewalHandlerTest.php
This commit is contained in:
commit
392d27f08b
163 changed files with 13687 additions and 1746 deletions
|
@ -40,11 +40,6 @@ const bootstrap = () => {
|
|||
);
|
||||
const spinner = new Spinner();
|
||||
|
||||
let creditCardRenderer = new HostedFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner);
|
||||
if (typeof paypal.CardFields !== 'undefined') {
|
||||
creditCardRenderer = new CardFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner);
|
||||
}
|
||||
|
||||
const formSaver = new FormSaver(
|
||||
PayPalCommerceGateway.ajax.save_checkout_form.endpoint,
|
||||
PayPalCommerceGateway.ajax.save_checkout_form.nonce,
|
||||
|
@ -73,13 +68,7 @@ const bootstrap = () => {
|
|||
&& document.querySelector(PayPalCommerceGateway.messages.wrapper);
|
||||
}
|
||||
|
||||
const onSmartButtonClick = async (data, actions) => {
|
||||
window.ppcpFundingSource = data.fundingSource;
|
||||
const requiredFields = jQuery('form.woocommerce-checkout .validate-required:visible :input');
|
||||
requiredFields.each((i, input) => {
|
||||
jQuery(input).trigger('validate');
|
||||
});
|
||||
|
||||
const doBasicCheckoutValidation = () => {
|
||||
if (PayPalCommerceGateway.basic_checkout_validation_enabled) {
|
||||
// A quick fix to get the errors about empty form fields before attempting PayPal order,
|
||||
// it should solve #513 for most of the users, but it is not a proper solution.
|
||||
|
@ -117,9 +106,26 @@ const bootstrap = () => {
|
|||
errorHandler.message(PayPalCommerceGateway.labels.error.required.generic);
|
||||
}
|
||||
|
||||
return actions.reject();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const onCardFieldsBeforeSubmit = () => {
|
||||
return doBasicCheckoutValidation();
|
||||
};
|
||||
|
||||
const onSmartButtonClick = async (data, actions) => {
|
||||
window.ppcpFundingSource = data.fundingSource;
|
||||
const requiredFields = jQuery('form.woocommerce-checkout .validate-required:visible :input');
|
||||
requiredFields.each((i, input) => {
|
||||
jQuery(input).trigger('validate');
|
||||
});
|
||||
|
||||
if (!doBasicCheckoutValidation()) {
|
||||
return actions.reject();
|
||||
}
|
||||
|
||||
const form = document.querySelector(checkoutFormSelector);
|
||||
if (form) {
|
||||
|
@ -131,7 +137,7 @@ const bootstrap = () => {
|
|||
}
|
||||
|
||||
const isFreeTrial = PayPalCommerceGateway.is_free_trial_cart;
|
||||
if (isFreeTrial && data.fundingSource !== 'card') {
|
||||
if (isFreeTrial && data.fundingSource !== 'card' && ! PayPalCommerceGateway.subscription_plan_id) {
|
||||
freeTrialHandler.handle();
|
||||
return actions.reject();
|
||||
}
|
||||
|
@ -149,6 +155,12 @@ const bootstrap = () => {
|
|||
jQuery(document).trigger('ppcp-smart-buttons-init', this);
|
||||
buttonsSpinner.unblock();
|
||||
};
|
||||
|
||||
let creditCardRenderer = new HostedFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner);
|
||||
if (typeof paypal.CardFields !== 'undefined') {
|
||||
creditCardRenderer = new CardFieldsRenderer(PayPalCommerceGateway, errorHandler, spinner, onCardFieldsBeforeSubmit);
|
||||
}
|
||||
|
||||
const renderer = new Renderer(creditCardRenderer, PayPalCommerceGateway, onSmartButtonClick, onSmartButtonsInit);
|
||||
const messageRenderer = new MessageRenderer(PayPalCommerceGateway.messages);
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ class ButtonModuleWatcher {
|
|||
}
|
||||
|
||||
watchContextBootstrap(callable) {
|
||||
console.log('ButtonModuleWatcher.js: watchContextBootstrap', this.contextBootstrapRegistry)
|
||||
this.contextBootstrapWatchers.push(callable);
|
||||
Object.values(this.contextBootstrapRegistry).forEach(callable);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
import {setVisible} from "../Helper/Hiding";
|
||||
import MessageRenderer from "../Renderer/MessageRenderer";
|
||||
|
||||
class MessagesBootstrap {
|
||||
constructor(gateway, messageRenderer) {
|
||||
this.gateway = gateway;
|
||||
this.renderer = messageRenderer;
|
||||
this.renderers = [];
|
||||
this.lastAmount = this.gateway.messages.amount;
|
||||
if (messageRenderer) {
|
||||
this.renderers.push(messageRenderer);
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
if (this.gateway.messages?.block?.enabled) {
|
||||
this.discoverBlocks();
|
||||
}
|
||||
jQuery(document.body).on('ppcp_cart_rendered ppcp_checkout_rendered', () => {
|
||||
this.render();
|
||||
});
|
||||
|
@ -16,7 +23,7 @@ class MessagesBootstrap {
|
|||
|
||||
this.render();
|
||||
});
|
||||
jQuery(document.body).on('ppcp_cart_total_updated ppcp_checkout_total_updated ppcp_product_total_updated', (e, amount) => {
|
||||
jQuery(document.body).on('ppcp_cart_total_updated ppcp_checkout_total_updated ppcp_product_total_updated ppcp_block_cart_total_updated', (e, amount) => {
|
||||
if (this.lastAmount !== amount) {
|
||||
this.lastAmount = amount;
|
||||
|
||||
|
@ -27,28 +34,40 @@ class MessagesBootstrap {
|
|||
this.render();
|
||||
}
|
||||
|
||||
shouldShow() {
|
||||
discoverBlocks() {
|
||||
Array.from(document.querySelectorAll('.ppcp-paylater-message-block')).forEach(blockElement => {
|
||||
const config = {wrapper: '#' + blockElement.id};
|
||||
if (!blockElement.getAttribute('data-pp-placement')) {
|
||||
config.placement = this.gateway.messages.placement;
|
||||
}
|
||||
this.renderers.push(new MessageRenderer(config));
|
||||
});
|
||||
}
|
||||
|
||||
shouldShow(renderer) {
|
||||
if (this.gateway.messages.is_hidden === true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const eventData = {result: true}
|
||||
jQuery(document.body).trigger('ppcp_should_show_messages', [eventData]);
|
||||
jQuery(document.body).trigger('ppcp_should_show_messages', [eventData, renderer.config.wrapper]);
|
||||
return eventData.result;
|
||||
}
|
||||
|
||||
shouldRender() {
|
||||
return this.shouldShow() && this.renderer.shouldRender();
|
||||
}
|
||||
|
||||
render() {
|
||||
setVisible(this.gateway.messages.wrapper, this.shouldShow());
|
||||
this.renderers.forEach(renderer => {
|
||||
const shouldShow = this.shouldShow(renderer);
|
||||
setVisible(renderer.config.wrapper, shouldShow);
|
||||
if (!shouldShow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.shouldRender()) {
|
||||
return;
|
||||
}
|
||||
if (!renderer.shouldRender()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.renderer.renderWithAmount(this.lastAmount);
|
||||
renderer.renderWithAmount(this.lastAmount);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ export class ApmButtons {
|
|||
this.refresh();
|
||||
});
|
||||
|
||||
jQuery(document).on('ppcp-shown ppcp-hidden ppcp-enabled ppcp-disabled', (ev, data) => {
|
||||
this.refresh();
|
||||
setTimeout(this.refresh.bind(this), 200);
|
||||
});
|
||||
|
||||
// Observes for new buttons.
|
||||
(new MutationObserver(this.observeElementsCallback.bind(this)))
|
||||
.observe(document.body, { childList: true, subtree: true });
|
||||
|
@ -72,7 +77,6 @@ export class ApmButtons {
|
|||
this.containers.push(parent);
|
||||
}
|
||||
});
|
||||
console.log('this.containers', this.containers);
|
||||
}
|
||||
|
||||
refresh() {
|
||||
|
@ -104,8 +108,10 @@ export class ApmButtons {
|
|||
return true;
|
||||
}
|
||||
|
||||
const minMargin = 11; // Minimum margin.
|
||||
const height = $el.height();
|
||||
$el.css('margin-top', `${Math.round(height * 0.3)}px`);
|
||||
const margin = Math.max(minMargin, Math.round(height * 0.3));
|
||||
$el.css('margin-top', `${margin}px`);
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -56,10 +56,12 @@ export const loadPaypalScript = (config, onLoaded, onError = null) => {
|
|||
|
||||
// Build the PayPal script options.
|
||||
let scriptOptions = keysToCamelCase(config.url_params);
|
||||
scriptOptions = merge(scriptOptions, config.script_attributes);
|
||||
if (config.script_attributes) {
|
||||
scriptOptions = merge(scriptOptions, config.script_attributes);
|
||||
}
|
||||
|
||||
// Load PayPal script for special case with data-client-token
|
||||
if (config.data_client_id.set_attribute) {
|
||||
if (config.data_client_id?.set_attribute) {
|
||||
dataClientIdAttributeHandler(scriptOptions, config.data_client_id, callback, errorCallback);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import {cardFieldStyles} from "../Helper/CardFieldsHelper";
|
|||
|
||||
class CardFieldsRenderer {
|
||||
|
||||
constructor(defaultConfig, errorHandler, spinner) {
|
||||
constructor(defaultConfig, errorHandler, spinner, onCardFieldsBeforeSubmit) {
|
||||
this.defaultConfig = defaultConfig;
|
||||
this.errorHandler = errorHandler;
|
||||
this.spinner = spinner;
|
||||
|
@ -11,6 +11,7 @@ class CardFieldsRenderer {
|
|||
this.formValid = false;
|
||||
this.emptyFields = new Set(['number', 'cvv', 'expirationDate']);
|
||||
this.currentHostedFieldsInstance = null;
|
||||
this.onCardFieldsBeforeSubmit = onCardFieldsBeforeSubmit;
|
||||
}
|
||||
|
||||
render(wrapper, contextConfig) {
|
||||
|
@ -55,28 +56,52 @@ class CardFieldsRenderer {
|
|||
const nameField = document.getElementById('ppcp-credit-card-gateway-card-name');
|
||||
if (nameField) {
|
||||
let styles = cardFieldStyles(nameField);
|
||||
cardField.NameField({style: {'input': styles}}).render(nameField.parentNode);
|
||||
let fieldOptions = {
|
||||
style: { 'input': styles }
|
||||
}
|
||||
if (nameField.getAttribute('placeholder')) {
|
||||
fieldOptions.placeholder = nameField.getAttribute('placeholder');
|
||||
}
|
||||
cardField.NameField(fieldOptions).render(nameField.parentNode);
|
||||
nameField.remove();
|
||||
}
|
||||
|
||||
const numberField = document.getElementById('ppcp-credit-card-gateway-card-number');
|
||||
if (numberField) {
|
||||
let styles = cardFieldStyles(numberField);
|
||||
cardField.NumberField({style: {'input': styles}}).render(numberField.parentNode);
|
||||
let fieldOptions = {
|
||||
style: { 'input': styles }
|
||||
}
|
||||
if (numberField.getAttribute('placeholder')) {
|
||||
fieldOptions.placeholder = numberField.getAttribute('placeholder');
|
||||
}
|
||||
cardField.NumberField(fieldOptions).render(numberField.parentNode);
|
||||
numberField.remove();
|
||||
}
|
||||
|
||||
const expiryField = document.getElementById('ppcp-credit-card-gateway-card-expiry');
|
||||
if (expiryField) {
|
||||
let styles = cardFieldStyles(expiryField);
|
||||
cardField.ExpiryField({style: {'input': styles}}).render(expiryField.parentNode);
|
||||
let fieldOptions = {
|
||||
style: { 'input': styles }
|
||||
}
|
||||
if (expiryField.getAttribute('placeholder')) {
|
||||
fieldOptions.placeholder = expiryField.getAttribute('placeholder');
|
||||
}
|
||||
cardField.ExpiryField(fieldOptions).render(expiryField.parentNode);
|
||||
expiryField.remove();
|
||||
}
|
||||
|
||||
const cvvField = document.getElementById('ppcp-credit-card-gateway-card-cvc');
|
||||
if (cvvField) {
|
||||
let styles = cardFieldStyles(cvvField);
|
||||
cardField.CVVField({style: {'input': styles}}).render(cvvField.parentNode);
|
||||
let fieldOptions = {
|
||||
style: { 'input': styles }
|
||||
}
|
||||
if (cvvField.getAttribute('placeholder')) {
|
||||
fieldOptions.placeholder = cvvField.getAttribute('placeholder');
|
||||
}
|
||||
cardField.CVVField(fieldOptions).render(cvvField.parentNode);
|
||||
cvvField.remove();
|
||||
}
|
||||
|
||||
|
@ -87,6 +112,14 @@ class CardFieldsRenderer {
|
|||
|
||||
show(buttonSelector);
|
||||
|
||||
if(this.defaultConfig.cart_contains_subscription) {
|
||||
const saveToAccount = document.querySelector('#wc-ppcp-credit-card-gateway-new-payment-method');
|
||||
if(saveToAccount) {
|
||||
saveToAccount.checked = true;
|
||||
saveToAccount.disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector(buttonSelector).addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
this.spinner.block();
|
||||
|
@ -94,19 +127,12 @@ class CardFieldsRenderer {
|
|||
|
||||
const paymentToken = document.querySelector('input[name="wc-ppcp-credit-card-gateway-payment-token"]:checked')?.value
|
||||
if(paymentToken && paymentToken !== 'new') {
|
||||
fetch(this.defaultConfig.ajax.capture_card_payment.endpoint, {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
body: JSON.stringify({
|
||||
nonce: this.defaultConfig.ajax.capture_card_payment.nonce,
|
||||
payment_token: paymentToken
|
||||
})
|
||||
}).then((res) => {
|
||||
return res.json();
|
||||
}).then((data) => {
|
||||
document.querySelector('#place_order').click();
|
||||
});
|
||||
document.querySelector('#place_order').click();
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof this.onCardFieldsBeforeSubmit === 'function' && !this.onCardFieldsBeforeSubmit()) {
|
||||
this.spinner.unblock();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,13 @@ class MessageRenderer {
|
|||
|
||||
const options = {
|
||||
amount,
|
||||
placement: this.config.placement,
|
||||
style: this.config.style
|
||||
};
|
||||
if (this.config.placement) {
|
||||
options.placement = this.config.placement;
|
||||
}
|
||||
if (this.config.style) {
|
||||
options.style = this.config.style;
|
||||
}
|
||||
|
||||
// sometimes the element is destroyed while the options stay the same
|
||||
if (document.querySelector(this.config.wrapper).getAttribute('data-render-number') !== this.currentNumber.toString()) {
|
||||
|
|
|
@ -32,6 +32,7 @@ use WooCommerce\PayPalCommerce\Button\Endpoint\ValidateCheckoutEndpoint;
|
|||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\PayLaterBlock\PayLaterBlockModule;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\FreeTrialHandlerTrait;
|
||||
use WooCommerce\PayPalCommerce\WcSubscriptions\Helper\SubscriptionHelper;
|
||||
|
@ -393,7 +394,7 @@ class SmartButton implements SmartButtonInterface {
|
|||
* @return bool
|
||||
*/
|
||||
private function render_message_wrapper_registrar(): bool {
|
||||
if ( ! $this->settings_status->is_pay_later_messaging_enabled() ) {
|
||||
if ( ! $this->settings_status->is_pay_later_messaging_enabled() || ! $this->settings_status->has_pay_later_messaging_locations() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -605,7 +606,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
case 'product':
|
||||
return $smart_button_enabled_for_current_location || $smart_button_enabled_for_mini_cart;
|
||||
default:
|
||||
return $smart_button_enabled_for_mini_cart;
|
||||
return $smart_button_enabled_for_mini_cart || $this->is_block_editor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,6 +619,10 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->settings_status->is_pay_later_messaging_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->messages_apply->for_country() || $this->is_free_trial_cart() ) {
|
||||
return false;
|
||||
}
|
||||
|
@ -626,6 +631,8 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
|
||||
$messaging_enabled_for_current_location = $this->settings_status->is_pay_later_messaging_enabled_for_location( $location );
|
||||
|
||||
$has_paylater_block = has_block( 'woocommerce-paypal-payments/paylater-messages' ) && PayLaterBlockModule::is_block_enabled( $this->settings_status );
|
||||
|
||||
switch ( $location ) {
|
||||
case 'checkout':
|
||||
case 'cart':
|
||||
|
@ -634,8 +641,13 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
case 'shop':
|
||||
case 'home':
|
||||
return $messaging_enabled_for_current_location;
|
||||
case 'block-editor':
|
||||
return true;
|
||||
case 'checkout-block':
|
||||
case 'cart-block':
|
||||
return $has_paylater_block || $this->is_block_editor();
|
||||
default:
|
||||
return false;
|
||||
return $has_paylater_block;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -843,9 +855,10 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
}
|
||||
|
||||
$product = wc_get_product();
|
||||
$amount = ( is_a( $product, WC_Product::class ) ) ? wc_get_price_including_tax( $product ) : 0;
|
||||
|
||||
if ( is_checkout() || is_cart() ) {
|
||||
$amount = 0;
|
||||
if ( is_a( $product, WC_Product::class ) ) {
|
||||
$amount = wc_get_price_including_tax( $product );
|
||||
} elseif ( isset( WC()->cart ) ) {
|
||||
$amount = WC()->cart->get_total( 'raw' );
|
||||
}
|
||||
|
||||
|
@ -859,10 +872,14 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
$text_color = $this->settings->has( "{$setting_name_prefix}_color" ) ? $this->settings->get( "{$setting_name_prefix}_color" ) : 'black';
|
||||
$style_color = $this->settings->has( "{$setting_name_prefix}_flex_color" ) ? $this->settings->get( "{$setting_name_prefix}_flex_color" ) : 'blue';
|
||||
$ratio = $this->settings->has( "{$setting_name_prefix}_flex_ratio" ) ? $this->settings->get( "{$setting_name_prefix}_flex_ratio" ) : '1x1';
|
||||
$text_size = $this->settings->has( "{$setting_name_prefix}_text_size" ) ? $this->settings->get( "{$setting_name_prefix}_text_size" ) : '12';
|
||||
|
||||
return array(
|
||||
'wrapper' => '#ppcp-messages',
|
||||
'is_hidden' => ! $this->is_pay_later_filter_enabled_for_location( $this->context() ),
|
||||
'block' => array(
|
||||
'enabled' => PayLaterBlockModule::is_block_enabled( $this->settings_status ),
|
||||
),
|
||||
'amount' => $amount,
|
||||
'placement' => $placement,
|
||||
'style' => array(
|
||||
|
@ -873,12 +890,12 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
),
|
||||
'text' => array(
|
||||
'color' => $text_color,
|
||||
'size' => $text_size,
|
||||
),
|
||||
'color' => $style_color,
|
||||
'ratio' => $ratio,
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -933,7 +950,10 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* @return bool
|
||||
*/
|
||||
private function has_subscriptions(): bool {
|
||||
if ( ! $this->subscription_helper->accept_only_automatic_payment_gateways() ) {
|
||||
if (
|
||||
! $this->subscription_helper->accept_only_automatic_payment_gateways()
|
||||
&& $this->paypal_subscriptions_enabled() !== true
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if ( is_product() ) {
|
||||
|
@ -1041,6 +1061,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
'endpoint' => \WC_AJAX::get_endpoint( CartScriptParamsEndpoint::ENDPOINT ),
|
||||
),
|
||||
),
|
||||
'cart_contains_subscription' => $this->subscription_helper->cart_contains_subscription(),
|
||||
'subscription_plan_id' => $this->subscription_helper->paypal_subscription_id(),
|
||||
'variable_paypal_subscription_variations' => $this->subscription_helper->variable_paypal_subscription_variations(),
|
||||
'subscription_product_allowed' => $this->subscription_helper->checkout_subscription_product_allowed(),
|
||||
|
@ -1154,6 +1175,9 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
'basic_checkout_validation_enabled' => $this->basic_checkout_validation_enabled,
|
||||
'early_checkout_validation_enabled' => $this->early_validation_enabled,
|
||||
'funding_sources_without_redirect' => $this->funding_sources_without_redirect,
|
||||
'user' => array(
|
||||
'is_logged' => is_user_logged_in(),
|
||||
),
|
||||
);
|
||||
|
||||
if ( 'pay-now' === $this->context() ) {
|
||||
|
@ -1237,6 +1261,16 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
'commit' => in_array( $context, $this->pay_now_contexts, true ) ? 'true' : 'false',
|
||||
'intent' => $intent,
|
||||
);
|
||||
|
||||
if (
|
||||
$this->settings->has( 'subscriptions_mode' )
|
||||
&& $this->settings->get( 'subscriptions_mode' ) === 'vaulting_api'
|
||||
&& apply_filters( 'woocommerce_paypal_payments_save_payment_methods_eligible', false )
|
||||
) {
|
||||
// Remove vault parameter to allow for Venmo with Save Payment Methods (Vault V3).
|
||||
unset( $params['vault'] );
|
||||
}
|
||||
|
||||
if (
|
||||
$this->environment->current_environment_is( Environment::SANDBOX )
|
||||
&& defined( 'WP_DEBUG' ) && \WP_DEBUG
|
||||
|
@ -1447,8 +1481,8 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
$context = 'general';
|
||||
}
|
||||
|
||||
return $this->get_style_value( "button_{$context}_${style}" )
|
||||
?? $this->get_style_value( "button_${style}" )
|
||||
return $this->get_style_value( "button_{$context}_{$style}" )
|
||||
?? $this->get_style_value( "button_{$style}" )
|
||||
?? ( $default ? $this->normalize_style_value( $default ) : null )
|
||||
?? $this->normalize_style_value( $defaults[ $style ] ?? '' );
|
||||
}
|
||||
|
@ -1463,7 +1497,7 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* @return string|int
|
||||
*/
|
||||
private function style_for_apm( string $style, string $apm, $default = null ) {
|
||||
return $this->get_style_value( "${apm}_button_${style}" )
|
||||
return $this->get_style_value( "{$apm}_button_{$style}" )
|
||||
?? ( $default ? $this->normalize_style_value( $default ) : null )
|
||||
?? $this->style_for_context( $style, 'checkout' );
|
||||
}
|
||||
|
@ -1584,14 +1618,14 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* The filter returning the action name that will be used for rendering Pay Later messages.
|
||||
*/
|
||||
$hook = (string) apply_filters(
|
||||
"woocommerce_paypal_payments_${location_hook}_messages_renderer_hook",
|
||||
"woocommerce_paypal_payments_{$location_hook}_messages_renderer_hook",
|
||||
$default_hook
|
||||
);
|
||||
/**
|
||||
* The filter returning the action priority that will be used for rendering Pay Later messages.
|
||||
*/
|
||||
$priority = (int) apply_filters(
|
||||
"woocommerce_paypal_payments_${location_hook}_messages_renderer_priority",
|
||||
"woocommerce_paypal_payments_{$location_hook}_messages_renderer_priority",
|
||||
$default_priority
|
||||
);
|
||||
return array(
|
||||
|
@ -1615,14 +1649,14 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
|||
* The filter returning the action name that will be used for rendering Pay Later messages.
|
||||
*/
|
||||
$block_name = (string) apply_filters(
|
||||
"woocommerce_paypal_payments_${location_hook}_messages_renderer_block",
|
||||
"woocommerce_paypal_payments_{$location_hook}_messages_renderer_block",
|
||||
$default_block
|
||||
);
|
||||
/**
|
||||
* The filter returning the action priority that will be used for rendering Pay Later messages.
|
||||
*/
|
||||
$priority = (int) apply_filters(
|
||||
"woocommerce_paypal_payments_${location_hook}_messages_renderer_block_priority",
|
||||
"woocommerce_paypal_payments_{$location_hook}_messages_renderer_block_priority",
|
||||
$default_priority
|
||||
);
|
||||
return array(
|
||||
|
|
|
@ -13,6 +13,7 @@ use Psr\Log\LoggerInterface;
|
|||
use Throwable;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
|
||||
/**
|
||||
* Class CartScriptParamsEndpoint.
|
||||
|
@ -25,7 +26,7 @@ class CartScriptParamsEndpoint implements EndpointInterface {
|
|||
/**
|
||||
* The SmartButton.
|
||||
*
|
||||
* @var SmartButton
|
||||
* @var SmartButtonInterface
|
||||
*/
|
||||
private $smart_button;
|
||||
|
||||
|
@ -39,11 +40,11 @@ class CartScriptParamsEndpoint implements EndpointInterface {
|
|||
/**
|
||||
* CartScriptParamsEndpoint constructor.
|
||||
*
|
||||
* @param SmartButton $smart_button he SmartButton.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param SmartButtonInterface $smart_button he SmartButton.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
SmartButton $smart_button,
|
||||
SmartButtonInterface $smart_button,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->smart_button = $smart_button;
|
||||
|
@ -66,6 +67,11 @@ class CartScriptParamsEndpoint implements EndpointInterface {
|
|||
*/
|
||||
public function handle_request(): bool {
|
||||
try {
|
||||
if ( ! $this->smart_button instanceof SmartButton ) {
|
||||
wp_send_json_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_callable( 'wc_maybe_define_constant' ) ) {
|
||||
wc_maybe_define_constant( 'WOOCOMMERCE_CART', true );
|
||||
}
|
||||
|
@ -73,6 +79,10 @@ class CartScriptParamsEndpoint implements EndpointInterface {
|
|||
$include_shipping = (bool) wc_clean( wp_unslash( $_GET['shipping'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
$script_data = $this->smart_button->script_data();
|
||||
if ( ! $script_data ) {
|
||||
wp_send_json_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
$total = (float) WC()->cart->get_total( 'numeric' );
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|||
if ( $this->early_validation_enabled
|
||||
&& $this->form
|
||||
&& 'checkout' === $data['context']
|
||||
&& in_array( $payment_method, array( PayPalGateway::ID, CardButtonGateway::ID ), true )
|
||||
&& in_array( $payment_method, array( PayPalGateway::ID, CardButtonGateway::ID, CreditCardGateway::ID ), true )
|
||||
) {
|
||||
$this->validate_form( $this->form );
|
||||
}
|
||||
|
@ -422,6 +422,7 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|||
*
|
||||
* @throws RuntimeException If create order request fails.
|
||||
* @throws PayPalApiException If create order request fails.
|
||||
*
|
||||
* phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
private function create_paypal_order( \WC_Order $wc_order = null, string $payment_method = '', array $data = array() ): Order {
|
||||
|
|
|
@ -13,6 +13,7 @@ use Exception;
|
|||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButtonInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\CartProductsHelper;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +26,7 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
|||
/**
|
||||
* The SmartButton.
|
||||
*
|
||||
* @var SmartButton
|
||||
* @var SmartButtonInterface
|
||||
*/
|
||||
private $smart_button;
|
||||
|
||||
|
@ -39,14 +40,14 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
|||
/**
|
||||
* ChangeCartEndpoint constructor.
|
||||
*
|
||||
* @param SmartButton $smart_button The SmartButton.
|
||||
* @param \WC_Cart $cart The current WC cart object.
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param CartProductsHelper $cart_products The cart products helper.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param SmartButtonInterface $smart_button The SmartButton.
|
||||
* @param \WC_Cart $cart The current WC cart object.
|
||||
* @param RequestData $request_data The request data helper.
|
||||
* @param CartProductsHelper $cart_products The cart products helper.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
SmartButton $smart_button,
|
||||
SmartButtonInterface $smart_button,
|
||||
\WC_Cart $cart,
|
||||
RequestData $request_data,
|
||||
CartProductsHelper $cart_products,
|
||||
|
@ -68,6 +69,11 @@ class SimulateCartEndpoint extends AbstractCartEndpoint {
|
|||
* @throws Exception On error.
|
||||
*/
|
||||
protected function handle_data(): bool {
|
||||
if ( ! $this->smart_button instanceof SmartButton ) {
|
||||
wp_send_json_error();
|
||||
return false;
|
||||
}
|
||||
|
||||
$products = $this->products_from_request();
|
||||
|
||||
if ( ! $products ) {
|
||||
|
|
|
@ -131,6 +131,10 @@ trait ContextTrait {
|
|||
return 'add-payment-method';
|
||||
}
|
||||
|
||||
if ( $this->is_block_editor() ) {
|
||||
return 'block-editor';
|
||||
}
|
||||
|
||||
return 'mini-cart';
|
||||
}
|
||||
|
||||
|
@ -207,4 +211,28 @@ trait ContextTrait {
|
|||
|
||||
return $page_id && is_page( $page_id ) && isset( $wp->query_vars['add-payment-method'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this user is changing the payment method for a subscription.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_subscription_change_payment_method_page(): bool {
|
||||
if ( isset( $_GET['change_payment_method'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
|
||||
return wcs_is_subscription( wc_clean( wp_unslash( $_GET['change_payment_method'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if it is the block editor page.
|
||||
*/
|
||||
protected function is_block_editor(): bool {
|
||||
if ( ! function_exists( 'get_current_screen' ) ) {
|
||||
return false;
|
||||
}
|
||||
$screen = get_current_screen();
|
||||
return $screen && $screen->is_block_editor();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,10 +67,10 @@ class ThreeDSecure {
|
|||
return self::NO_DECISION;
|
||||
}
|
||||
|
||||
if ( ! $payment_source->properties()->brand ?? '' ) {
|
||||
if ( ! ( $payment_source->properties()->brand ?? '' ) ) {
|
||||
return self::NO_DECISION;
|
||||
}
|
||||
if ( ! $payment_source->properties()->authentication_result ?? '' ) {
|
||||
if ( ! ( $payment_source->properties()->authentication_result ?? '' ) ) {
|
||||
return self::NO_DECISION;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ class ThreeDSecure {
|
|||
if ( $authentication_result ) {
|
||||
$result = $this->card_authentication_result_factory->from_paypal_response( $authentication_result );
|
||||
|
||||
$this->logger->info( '3DS authentication result: ' . wc_print_r( $result->to_array(), true ) );
|
||||
$this->logger->info( '3DS Authentication Result: ' . wc_print_r( $result->to_array(), true ) );
|
||||
|
||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
|
||||
return self::PROCCEED;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue