mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-01 07:02:48 +08:00
Fix merge conflicts
This commit is contained in:
commit
f50628adad
22 changed files with 547 additions and 286 deletions
|
@ -99,6 +99,26 @@ class Token {
|
|||
return new Token( $json );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if vaulting is available in access token scope.
|
||||
*
|
||||
* @return bool Whether vaulting features are enabled or not.
|
||||
*/
|
||||
public function vaulting_available(): bool {
|
||||
if ( ! isset( $this->json->scope ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( strpos(
|
||||
$this->json->scope,
|
||||
'https://uri.paypal.com/services/vault/payment-tokens/readwrite'
|
||||
) !== false ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether a JSON object can be transformed to a Token object.
|
||||
*
|
||||
|
|
|
@ -91,7 +91,7 @@ class ItemFactory {
|
|||
*
|
||||
* @var \WC_Product $product
|
||||
*/
|
||||
$quantity = $item->get_quantity();
|
||||
$quantity = (int) $item->get_quantity();
|
||||
|
||||
$price = (float) $order->get_item_subtotal( $item, true );
|
||||
$price_without_tax = (float) $order->get_item_subtotal( $item, false );
|
||||
|
|
|
@ -119,7 +119,7 @@ class PurchaseUnitFactory {
|
|||
$reference_id = 'default';
|
||||
$description = '';
|
||||
$payee = $this->payee_repository->payee();
|
||||
$wc_order_id = $order->get_id();
|
||||
$wc_order_id = $order->get_order_number();
|
||||
$custom_id = $this->prefix . $wc_order_id;
|
||||
$invoice_id = $this->prefix . $wc_order_id;
|
||||
$soft_descriptor = '';
|
||||
|
@ -134,7 +134,11 @@ class PurchaseUnitFactory {
|
|||
$invoice_id,
|
||||
$soft_descriptor
|
||||
);
|
||||
return $purchase_unit;
|
||||
return apply_filters(
|
||||
'woocommerce_paypal_payments_purchase_unit_from_wc_order',
|
||||
$purchase_unit,
|
||||
$order
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ class ApplicationContextRepository {
|
|||
): ApplicationContext {
|
||||
|
||||
$brand_name = $this->settings->has( 'brand_name' ) ? $this->settings->get( 'brand_name' ) : '';
|
||||
$locale = str_replace( '_', '-', get_user_locale() );
|
||||
$locale = $this->valid_bcp47_code();
|
||||
$landingpage = $this->settings->has( 'landing_page' ) ?
|
||||
$this->settings->get( 'landing_page' ) : ApplicationContext::LANDING_PAGE_NO_PREFERENCE;
|
||||
$context = new ApplicationContext(
|
||||
|
@ -59,4 +59,24 @@ class ApplicationContextRepository {
|
|||
);
|
||||
return $context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a PayPal-supported BCP-47 code, for example de-DE-formal becomes de-DE.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function valid_bcp47_code() {
|
||||
$locale = str_replace( '_', '-', get_user_locale() );
|
||||
|
||||
if ( preg_match( '/^[a-z]{2}(?:-[A-Z][a-z]{3})?(?:-(?:[A-Z]{2}))?$/', $locale ) ) {
|
||||
return $locale;
|
||||
}
|
||||
|
||||
$parts = explode( '-', $locale );
|
||||
if ( count( $parts ) === 3 ) {
|
||||
return substr( $locale, 0, strrpos( $locale, '-' ) );
|
||||
}
|
||||
|
||||
return 'en';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ class PartnerReferralsData {
|
|||
'FUTURE_PAYMENT',
|
||||
'REFUND',
|
||||
'ADVANCED_TRANSACTIONS_SEARCH',
|
||||
'VAULT',
|
||||
),
|
||||
'seller_nonce' => $this->nonce(),
|
||||
),
|
||||
|
|
|
@ -87,7 +87,7 @@ class CreditCardRenderer {
|
|||
},
|
||||
expirationDate: {
|
||||
selector: '#ppcp-credit-card-gateway-card-expiry',
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.mm_yyyy,
|
||||
placeholder: this.defaultConfig.hosted_fields.labels.mm_yy,
|
||||
}
|
||||
}
|
||||
}).then(hostedFields => {
|
||||
|
|
|
@ -665,7 +665,7 @@ class SmartButton implements SmartButtonInterface {
|
|||
'labels' => array(
|
||||
'credit_card_number' => '',
|
||||
'cvv' => '',
|
||||
'mm_yyyy' => __( 'MM/YYYY', 'woocommerce-paypal-payments' ),
|
||||
'mm_yy' => __( 'MM/YY', 'woocommerce-paypal-payments' ),
|
||||
'fields_not_valid' => __(
|
||||
'Unfortunately, your credit card details are not valid.',
|
||||
'woocommerce-paypal-payments'
|
||||
|
@ -724,7 +724,6 @@ class SmartButton implements SmartButtonInterface {
|
|||
$params = array(
|
||||
'client-id' => $this->client_id,
|
||||
'currency' => get_woocommerce_currency(),
|
||||
'locale' => get_user_locale(),
|
||||
'integration-date' => PAYPAL_INTEGRATION_DATE,
|
||||
'components' => implode( ',', $this->components() ),
|
||||
'vault' => $this->can_save_vault_token() ?
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace WooCommerce\PayPalCommerce\Button\Helper;
|
|||
class MessagesDisclaimers {
|
||||
|
||||
/**
|
||||
* Disclainers content by country.
|
||||
* Disclaimers content by country.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
|
|
|
@ -1,262 +1,297 @@
|
|||
const groupToggle = (selector, group) => {
|
||||
const toggleElement = document.querySelector(selector);
|
||||
if (! toggleElement) {
|
||||
return;
|
||||
}
|
||||
if (! toggleElement.checked) {
|
||||
group.forEach( (elementToHide) => {
|
||||
document.querySelector(elementToHide).style.display = 'none';
|
||||
})
|
||||
}
|
||||
toggleElement.addEventListener(
|
||||
'change',
|
||||
(event) => {
|
||||
|
||||
if (! event.target.checked) {
|
||||
group.forEach( (elementToHide) => {
|
||||
document.querySelector(elementToHide).style.display = 'none';
|
||||
});
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
const groupToggle = (selector, group) => {
|
||||
const toggleElement = document.querySelector(selector);
|
||||
if (! toggleElement) {
|
||||
return;
|
||||
}
|
||||
if (! toggleElement.checked) {
|
||||
group.forEach( (elementToHide) => {
|
||||
document.querySelector(elementToHide).style.display = 'none';
|
||||
})
|
||||
}
|
||||
toggleElement.addEventListener(
|
||||
'change',
|
||||
(event) => {
|
||||
|
||||
group.forEach( (elementToShow) => {
|
||||
document.querySelector(elementToShow).style.display = 'table-row';
|
||||
})
|
||||
}
|
||||
);
|
||||
};
|
||||
if (! event.target.checked) {
|
||||
group.forEach( (elementToHide) => {
|
||||
document.querySelector(elementToHide).style.display = 'none';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const groupToggleSelect = (selector, group) => {
|
||||
const toggleElement = document.querySelector(selector);
|
||||
if (! toggleElement) {
|
||||
return;
|
||||
}
|
||||
const value = toggleElement.value;
|
||||
group.forEach( (elementToToggle) => {
|
||||
const domElement = document.querySelector(elementToToggle.selector);
|
||||
if (! domElement) {
|
||||
return;
|
||||
}
|
||||
if (value === elementToToggle.value && domElement.style.display !== 'none') {
|
||||
domElement.style.display = 'table-row';
|
||||
return;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
});
|
||||
group.forEach( (elementToShow) => {
|
||||
document.querySelector(elementToShow).style.display = 'table-row';
|
||||
})
|
||||
|
||||
// We need to use jQuery here as the select might be a select2 element, which doesn't use native events.
|
||||
jQuery(toggleElement).on(
|
||||
'change',
|
||||
(event) => {
|
||||
const value = event.target.value;
|
||||
if('ppcp-message_enabled' === event.target.getAttribute('id')){
|
||||
updateCheckoutMessageFields();
|
||||
return;
|
||||
}
|
||||
|
||||
if('ppcp-message_product_enabled' === event.target.getAttribute('id')){
|
||||
updateProductMessageFields();
|
||||
return;
|
||||
}
|
||||
|
||||
if('ppcp-message_cart_enabled' === event.target.getAttribute('id')){
|
||||
updateCartMessageFields();
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const groupToggleSelect = (selector, group) => {
|
||||
const toggleElement = document.querySelector(selector);
|
||||
if (! toggleElement) {
|
||||
return;
|
||||
}
|
||||
const value = toggleElement.value;
|
||||
group.forEach( (elementToToggle) => {
|
||||
if (value === elementToToggle.value) {
|
||||
document.querySelector(elementToToggle.selector).style.display = 'table-row';
|
||||
const domElement = document.querySelector(elementToToggle.selector);
|
||||
if (! domElement) {
|
||||
return;
|
||||
}
|
||||
document.querySelector(elementToToggle.selector).style.display = 'none';
|
||||
})
|
||||
if (value === elementToToggle.value && domElement.style.display !== 'none') {
|
||||
domElement.style.display = 'table-row';
|
||||
return;
|
||||
}
|
||||
domElement.style.display = 'none';
|
||||
});
|
||||
|
||||
// We need to use jQuery here as the select might be a select2 element, which doesn't use native events.
|
||||
jQuery(toggleElement).on(
|
||||
'change',
|
||||
(event) => {
|
||||
const value = event.target.value;
|
||||
group.forEach( (elementToToggle) => {
|
||||
if (value === elementToToggle.value) {
|
||||
document.querySelector(elementToToggle.selector).style.display = 'table-row';
|
||||
return;
|
||||
}
|
||||
document.querySelector(elementToToggle.selector).style.display = 'none';
|
||||
})
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const updateCheckoutMessageFields = () => {
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const disableOptions = (sourceSelector, targetSelector) => {
|
||||
const updateProductMessageFields = () => {
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_product_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_product_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_product_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const source = jQuery(sourceSelector);
|
||||
const target = document.querySelector(targetSelector);
|
||||
if (! target) {
|
||||
return;
|
||||
const updateCartMessageFields = () =>
|
||||
{
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_cart_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_cart_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_cart_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const disableOptions = (sourceSelector, targetSelector) => {
|
||||
|
||||
const source = jQuery(sourceSelector);
|
||||
const target = document.querySelector(targetSelector);
|
||||
if (! target) {
|
||||
return;
|
||||
}
|
||||
const allOptions = Array.from(document.querySelectorAll('select[name="ppcp[disable_cards][]"] option'));
|
||||
const replace = () => {
|
||||
const validOptions = allOptions.filter(
|
||||
(option) => {
|
||||
|
||||
return ! option.selected
|
||||
}
|
||||
);
|
||||
const selectedValidOptions = validOptions.map(
|
||||
(option) => {
|
||||
option = option.cloneNode(true);
|
||||
option.selected = target.querySelector('option[value="' + option.value + '"]') && target.querySelector('option[value="' + option.value + '"]').selected;
|
||||
return option;
|
||||
}
|
||||
);
|
||||
target.innerHTML = '';
|
||||
selectedValidOptions.forEach(
|
||||
(option) => {
|
||||
target.append(option);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
source.on('change',replace);
|
||||
replace();
|
||||
};
|
||||
|
||||
(() => {
|
||||
disableOptions('select[name="ppcp[disable_cards][]"]', 'select[name="ppcp[card_icons][]"]');
|
||||
groupToggle(
|
||||
'#ppcp-button_enabled',
|
||||
[
|
||||
'#field-button_layout',
|
||||
'#field-button_tagline',
|
||||
'#field-button_label',
|
||||
'#field-button_color',
|
||||
'#field-button_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-message_enabled',
|
||||
[
|
||||
'#field-message_layout',
|
||||
'#field-message_logo',
|
||||
'#field-message_position',
|
||||
'#field-message_color',
|
||||
'#field-message_flex_color',
|
||||
'#field-message_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_product_enabled',
|
||||
[
|
||||
'#field-button_product_layout',
|
||||
'#field-button_product_tagline',
|
||||
'#field-button_product_label',
|
||||
'#field-button_product_color',
|
||||
'#field-button_product_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-message_product_enabled',
|
||||
[
|
||||
'#field-message_product_layout',
|
||||
'#field-message_product_logo',
|
||||
'#field-message_product_position',
|
||||
'#field-message_product_color',
|
||||
'#field-message_product_flex_color',
|
||||
'#field-message_product_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_mini-cart_enabled',
|
||||
[
|
||||
'#field-button_mini-cart_layout',
|
||||
'#field-button_mini-cart_tagline',
|
||||
'#field-button_mini-cart_label',
|
||||
'#field-button_mini-cart_color',
|
||||
'#field-button_mini-cart_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_cart_enabled',
|
||||
[
|
||||
'#field-button_cart_layout',
|
||||
'#field-button_cart_tagline',
|
||||
'#field-button_cart_label',
|
||||
'#field-button_cart_color',
|
||||
'#field-button_cart_shape',
|
||||
]
|
||||
);
|
||||
groupToggle(
|
||||
'#ppcp-message_cart_enabled',
|
||||
[
|
||||
'#field-message_cart_layout',
|
||||
'#field-message_cart_logo',
|
||||
'#field-message_cart_position',
|
||||
'#field-message_cart_color',
|
||||
'#field-message_cart_flex_color',
|
||||
'#field-message_cart_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
groupToggleSelect(
|
||||
'#ppcp-intent',
|
||||
[
|
||||
{
|
||||
value:'authorize',
|
||||
selector:'#field-capture_for_virtual_only'
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
updateCheckoutMessageFields();
|
||||
updateProductMessageFields();
|
||||
updateCartMessageFields();
|
||||
})();
|
||||
}
|
||||
const allOptions = Array.from(document.querySelectorAll('select[name="ppcp[disable_cards][]"] option'));
|
||||
const replace = () => {
|
||||
const validOptions = allOptions.filter(
|
||||
(option) => {
|
||||
|
||||
return ! option.selected
|
||||
}
|
||||
);
|
||||
const selectedValidOptions = validOptions.map(
|
||||
(option) => {
|
||||
option = option.cloneNode(true);
|
||||
option.selected = target.querySelector('option[value="' + option.value + '"]') && target.querySelector('option[value="' + option.value + '"]').selected;
|
||||
return option;
|
||||
}
|
||||
);
|
||||
target.innerHTML = '';
|
||||
selectedValidOptions.forEach(
|
||||
(option) => {
|
||||
target.append(option);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
source.on('change',replace);
|
||||
replace();
|
||||
};
|
||||
|
||||
(() => {
|
||||
disableOptions('select[name="ppcp[disable_cards][]"]', 'select[name="ppcp[card_icons][]"]');
|
||||
groupToggle(
|
||||
'#ppcp-button_enabled',
|
||||
[
|
||||
'#field-button_layout',
|
||||
'#field-button_tagline',
|
||||
'#field-button_label',
|
||||
'#field-button_color',
|
||||
'#field-button_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-message_enabled',
|
||||
[
|
||||
'#field-message_layout',
|
||||
'#field-message_logo',
|
||||
'#field-message_position',
|
||||
'#field-message_color',
|
||||
'#field-message_flex_color',
|
||||
'#field-message_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_product_enabled',
|
||||
[
|
||||
'#field-button_product_layout',
|
||||
'#field-button_product_tagline',
|
||||
'#field-button_product_label',
|
||||
'#field-button_product_color',
|
||||
'#field-button_product_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-message_product_enabled',
|
||||
[
|
||||
'#field-message_product_layout',
|
||||
'#field-message_product_logo',
|
||||
'#field-message_product_position',
|
||||
'#field-message_product_color',
|
||||
'#field-message_product_flex_color',
|
||||
'#field-message_product_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_mini-cart_enabled',
|
||||
[
|
||||
'#field-button_mini-cart_layout',
|
||||
'#field-button_mini-cart_tagline',
|
||||
'#field-button_mini-cart_label',
|
||||
'#field-button_mini-cart_color',
|
||||
'#field-button_mini-cart_shape',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggle(
|
||||
'#ppcp-button_cart_enabled',
|
||||
[
|
||||
'#field-button_cart_layout',
|
||||
'#field-button_cart_tagline',
|
||||
'#field-button_cart_label',
|
||||
'#field-button_cart_color',
|
||||
'#field-button_cart_shape',
|
||||
]
|
||||
);
|
||||
groupToggle(
|
||||
'#ppcp-message_cart_enabled',
|
||||
[
|
||||
'#field-message_cart_layout',
|
||||
'#field-message_cart_logo',
|
||||
'#field-message_cart_position',
|
||||
'#field-message_cart_color',
|
||||
'#field-message_cart_flex_color',
|
||||
'#field-message_cart_flex_ratio',
|
||||
]
|
||||
);
|
||||
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_product_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_product_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_product_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_product_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
groupToggleSelect(
|
||||
'#ppcp-intent',
|
||||
[
|
||||
{
|
||||
value:'authorize',
|
||||
selector:'#field-capture_for_virtual_only'
|
||||
}
|
||||
]
|
||||
);
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_cart_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_cart_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_cart_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_cart_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
groupToggleSelect(
|
||||
'#ppcp-message_layout',
|
||||
[
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_logo'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_position'
|
||||
},
|
||||
{
|
||||
value:'text',
|
||||
selector:'#field-message_color'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_flex_ratio'
|
||||
},
|
||||
{
|
||||
value:'flex',
|
||||
selector:'#field-message_flex_color'
|
||||
}
|
||||
]
|
||||
);
|
||||
})();
|
||||
)
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
function updateCheckboxes() {
|
||||
atLeastOneChecked(payLaterMessagingCheckboxes) ? disableAll(vaultingCheckboxes) : enableAll(vaultingCheckboxes)
|
||||
atLeastOneChecked(vaultingCheckboxes) ? disableAll(payLaterMessagingCheckboxes) : enableAll(payLaterMessagingCheckboxes)
|
||||
|
||||
if(PayPalCommerceGatewaySettings.vaulting_features_available !== '1' ) {
|
||||
disableAll(vaultingCheckboxes)
|
||||
}
|
||||
}
|
||||
|
||||
updateCheckboxes()
|
||||
|
|
|
@ -136,7 +136,8 @@ return array(
|
|||
$webhook_registrar = $container->get( 'webhook.registrar' );
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
$cache = new Cache( 'ppcp-paypal-bearer' );
|
||||
return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state );
|
||||
$bearer = $container->get( 'api.bearer' );
|
||||
return new SettingsListener( $settings, $fields, $webhook_registrar, $cache, $state, $bearer );
|
||||
},
|
||||
'wcgateway.order-processor' => static function ( $container ): OrderProcessor {
|
||||
|
||||
|
@ -184,7 +185,6 @@ return array(
|
|||
'wcgateway.settings.fields' => static function ( $container ): array {
|
||||
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
|
||||
|
||||
$fields = array(
|
||||
|
@ -637,8 +637,8 @@ return array(
|
|||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing href link tags.
|
||||
__( 'To use vaulting features, you must %1$senable vaulting on your account%2$s.', 'woocommerce-paypal-payments' ),
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Enable saved cards and subscription features on your store. To use vaulting features, you must %1$senable vaulting on your account%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a
|
||||
href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/#enable-vaulting-on-your-live-account"
|
||||
target="_blank"
|
||||
|
@ -1809,7 +1809,6 @@ return array(
|
|||
unset( $fields['disable_funding']['options']['card'] );
|
||||
}
|
||||
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
/**
|
||||
* Depending on your store location, some credit cards can't be used.
|
||||
* Here, we filter them out.
|
||||
|
@ -1818,6 +1817,7 @@ return array(
|
|||
*
|
||||
* @var DccApplies $dcc_applies
|
||||
*/
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
$card_options = $fields['disable_cards']['options'];
|
||||
foreach ( $card_options as $card => $label ) {
|
||||
if ( $dcc_applies->can_process_card( $card ) ) {
|
||||
|
@ -1827,6 +1827,18 @@ return array(
|
|||
}
|
||||
$fields['disable_cards']['options'] = $card_options;
|
||||
$fields['card_icons']['options'] = $card_options;
|
||||
|
||||
/**
|
||||
* Display vault message on Pay Later label if vault is enabled.
|
||||
*/
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
if ( $settings->has( 'vault_enabled' ) && $settings->get( 'vault_enabled' ) ) {
|
||||
$message = __( "You have PayPal vaulting enabled, that's why Pay Later Messaging options are unavailable now. You cannot use both features at the same time.", 'woocommerce-paypal-payments' );
|
||||
$fields['message_enabled']['label'] = $message;
|
||||
$fields['message_product_enabled']['label'] = $message;
|
||||
$fields['message_cart_enabled']['label'] = $message;
|
||||
}
|
||||
|
||||
return $fields;
|
||||
},
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
|
||||
/**
|
||||
* Class SettingsPageAssets
|
||||
*/
|
||||
|
@ -20,6 +22,7 @@ class SettingsPageAssets {
|
|||
* @var string
|
||||
*/
|
||||
private $module_url;
|
||||
|
||||
/**
|
||||
* The filesystem path to the module dir.
|
||||
*
|
||||
|
@ -27,24 +30,34 @@ class SettingsPageAssets {
|
|||
*/
|
||||
private $module_path;
|
||||
|
||||
/**
|
||||
* The bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* Assets constructor.
|
||||
*
|
||||
* @param string $module_url The url of this module.
|
||||
* @param string $module_path The filesystem path to this module.
|
||||
* @param Bearer $bearer The bearer.
|
||||
*/
|
||||
public function __construct( string $module_url, string $module_path ) {
|
||||
public function __construct( string $module_url, string $module_path, Bearer $bearer ) {
|
||||
$this->module_url = $module_url;
|
||||
$this->module_path = $module_path;
|
||||
$this->bearer = $bearer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register assets provided by this module.
|
||||
*/
|
||||
public function register_assets() {
|
||||
$bearer = $this->bearer;
|
||||
add_action(
|
||||
'admin_enqueue_scripts',
|
||||
function() {
|
||||
function() use ( $bearer ) {
|
||||
if ( ! is_admin() || is_ajax() ) {
|
||||
return;
|
||||
}
|
||||
|
@ -53,7 +66,7 @@ class SettingsPageAssets {
|
|||
return;
|
||||
}
|
||||
|
||||
$this->register_admin_assets();
|
||||
$this->register_admin_assets( $bearer );
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -84,8 +97,10 @@ class SettingsPageAssets {
|
|||
|
||||
/**
|
||||
* Register assets for admin pages.
|
||||
*
|
||||
* @param Bearer $bearer The bearer.
|
||||
*/
|
||||
private function register_admin_assets() {
|
||||
private function register_admin_assets( Bearer $bearer ) {
|
||||
$gateway_settings_script_path = trailingslashit( $this->module_path ) . 'assets/js/gateway-settings.js';
|
||||
|
||||
wp_enqueue_script(
|
||||
|
@ -95,5 +110,14 @@ class SettingsPageAssets {
|
|||
file_exists( $gateway_settings_script_path ) ? (string) filemtime( $gateway_settings_script_path ) : null,
|
||||
true
|
||||
);
|
||||
|
||||
$token = $bearer->bearer();
|
||||
wp_localize_script(
|
||||
'ppcp-gateway-settings',
|
||||
'PayPalCommerceGatewaySettings',
|
||||
array(
|
||||
'vaulting_features_available' => $token->vaulting_available(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,6 +209,32 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the credit card fields.
|
||||
*/
|
||||
public function form() {
|
||||
add_action( 'gettext', array( $this, 'replace_credit_card_cvv_label' ), 10, 3 );
|
||||
parent::form();
|
||||
remove_action( 'gettext', 'replace_credit_card_cvv_label' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace WooCommerce credit card field label.
|
||||
*
|
||||
* @param string $translation Translated text.
|
||||
* @param string $text Original text to translate.
|
||||
* @param string $domain Text domain.
|
||||
*
|
||||
* @return string Translated field.
|
||||
*/
|
||||
public function replace_credit_card_cvv_label( string $translation, string $text, string $domain ): string {
|
||||
if ( 'woocommerce' !== $domain || 'Card code' !== $text ) {
|
||||
return $translation;
|
||||
}
|
||||
|
||||
return __( 'CVV', 'woocommerce-paypal-payments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the title of the gateway.
|
||||
*
|
||||
|
|
|
@ -227,10 +227,9 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
$wc_order->add_order_note(
|
||||
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
|
||||
$wc_order->set_status( 'processing' );
|
||||
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->save();
|
||||
$wc_order->payment_complete();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -239,11 +238,11 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
$wc_order->add_order_note(
|
||||
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
$wc_order->set_status( 'processing' );
|
||||
}
|
||||
|
||||
$wc_order->update_meta_data( self::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->save();
|
||||
$wc_order->payment_complete();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -184,10 +184,8 @@ class OrderProcessor {
|
|||
__( 'Awaiting payment.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
if ( $order->status()->is( OrderStatus::COMPLETED ) && $order->intent() === 'CAPTURE' ) {
|
||||
$wc_order->update_status(
|
||||
'processing',
|
||||
__( 'Payment received.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
|
||||
$wc_order->payment_complete();
|
||||
}
|
||||
|
||||
if ( $this->capture_authorized_downloads( $order ) && $this->authorized_payments_processor->process( $wc_order ) ) {
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
|
@ -21,7 +22,6 @@ use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
|
|||
*/
|
||||
class SettingsListener {
|
||||
|
||||
|
||||
const NONCE = 'ppcp-settings';
|
||||
|
||||
/**
|
||||
|
@ -59,6 +59,13 @@ class SettingsListener {
|
|||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* The Bearer.
|
||||
*
|
||||
* @var Bearer
|
||||
*/
|
||||
private $bearer;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
|
@ -67,13 +74,15 @@ class SettingsListener {
|
|||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param State $state The state.
|
||||
* @param Bearer $bearer The bearer.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
array $setting_fields,
|
||||
WebhookRegistrar $webhook_registrar,
|
||||
Cache $cache,
|
||||
State $state
|
||||
State $state,
|
||||
Bearer $bearer
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
|
@ -81,6 +90,7 @@ class SettingsListener {
|
|||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
$this->bearer = $bearer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,6 +147,13 @@ class SettingsListener {
|
|||
return;
|
||||
}
|
||||
|
||||
$token = $this->bearer->bearer();
|
||||
if ( ! $token->vaulting_available() ) {
|
||||
$this->settings->set( 'vault_enabled', false );
|
||||
$this->settings->persist();
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* No need to verify nonce here.
|
||||
*
|
||||
|
|
|
@ -76,7 +76,8 @@ class WcGatewayModule implements ModuleInterface {
|
|||
if ( $container->has( 'wcgateway.url' ) ) {
|
||||
$assets = new SettingsPageAssets(
|
||||
$container->get( 'wcgateway.url' ),
|
||||
$container->get( 'wcgateway.absolute-path' )
|
||||
$container->get( 'wcgateway.absolute-path' ),
|
||||
$container->get( 'api.bearer' )
|
||||
);
|
||||
$assets->register_assets();
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class PaymentCaptureCompleted implements RequestHandler {
|
|||
__( 'Payment successfully captured.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
|
||||
$wc_order->set_status( 'processing' );
|
||||
$wc_order->payment_complete();
|
||||
$wc_order->update_meta_data( PayPalGateway::CAPTURED_META_KEY, 'true' );
|
||||
$wc_order->save();
|
||||
$this->logger->log(
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Repository;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\TestCase;
|
||||
use WooCommerce\PayPalCommerce\Button\Assets\SmartButton;
|
||||
use function Brain\Monkey\Functions\when;
|
||||
|
||||
class ApplicationContextRepositoryTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provider
|
||||
*/
|
||||
public function test_valid_bcp47_code($input, $output)
|
||||
{
|
||||
$testee = $this->getMockBuilder(ApplicationContextRepository::class)
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$method = new \ReflectionMethod($testee, 'valid_bcp47_code');
|
||||
$method->setAccessible(true);
|
||||
|
||||
when('get_user_locale')->justReturn($input);
|
||||
|
||||
$this->assertSame($output, $method->invoke($testee));
|
||||
}
|
||||
|
||||
public function provider()
|
||||
{
|
||||
return [
|
||||
'de-DE' => ['de-DE', 'de-DE'],
|
||||
'de-DE-formal' => ['de-DE-formal', 'de-DE'],
|
||||
'de' => ['de', 'de'],
|
||||
'ceb' => ['ceb', 'en'],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -191,12 +191,11 @@ class WcGatewayTest extends TestCase
|
|||
$wcOrder = Mockery::mock(\WC_Order::class);
|
||||
$wcOrder
|
||||
->expects('add_order_note');
|
||||
$wcOrder
|
||||
->expects('set_status')
|
||||
->with('processing');
|
||||
$wcOrder
|
||||
->expects('update_meta_data')
|
||||
->with(PayPalGateway::CAPTURED_META_KEY, 'true');
|
||||
$wcOrder
|
||||
->expects('payment_complete');
|
||||
$wcOrder
|
||||
->expects('save');
|
||||
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
|
||||
|
@ -247,12 +246,11 @@ class WcGatewayTest extends TestCase
|
|||
->andReturn('on-hold');
|
||||
$wcOrder
|
||||
->expects('add_order_note');
|
||||
$wcOrder
|
||||
->expects('set_status')
|
||||
->with('processing');
|
||||
$wcOrder
|
||||
->expects('update_meta_data')
|
||||
->with(PayPalGateway::CAPTURED_META_KEY, 'true');
|
||||
$wcOrder
|
||||
->expects('payment_complete');
|
||||
$wcOrder
|
||||
->expects('save');
|
||||
$settingsRenderer = Mockery::mock(SettingsRenderer::class);
|
||||
|
|
|
@ -272,8 +272,7 @@ class OrderProcessorTest extends TestCase
|
|||
$wcOrder->expects('set_transaction_id')
|
||||
->with($transactionId);
|
||||
$wcOrder
|
||||
->expects('update_status')
|
||||
->with('processing', 'Payment received.');
|
||||
->expects('payment_complete');
|
||||
$this->assertTrue($testee->process($wcOrder));
|
||||
}
|
||||
|
||||
|
|
66
tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php
Normal file
66
tests/PHPUnit/WcGateway/Settings/SettingsListenerTest.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\TestCase;
|
||||
use Mockery;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
|
||||
use function Brain\Monkey\Functions\when;
|
||||
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
|
||||
|
||||
class SettingsListenerTest extends TestCase
|
||||
{
|
||||
use MockeryPHPUnitIntegration;
|
||||
|
||||
public function testListen()
|
||||
{
|
||||
$settings = Mockery::mock(Settings::class);
|
||||
$setting_fields = [];
|
||||
$webhook_registrar = Mockery::mock(WebhookRegistrar::class);
|
||||
$cache = Mockery::mock(Cache::class);
|
||||
$state = Mockery::mock(State::class);
|
||||
$bearer = Mockery::mock(Bearer::class);
|
||||
|
||||
$testee = new SettingsListener(
|
||||
$settings,
|
||||
$setting_fields,
|
||||
$webhook_registrar,
|
||||
$cache,
|
||||
$state,
|
||||
$bearer
|
||||
);
|
||||
|
||||
$_REQUEST['section'] = 'ppcp-gateway';
|
||||
$_POST['ppcp-nonce'] = 'foo';
|
||||
$_POST['ppcp'] = [
|
||||
'client_id' => 'client_id',
|
||||
];
|
||||
$_GET['ppcp-tab'] = 'just-a-tab';
|
||||
|
||||
when('sanitize_text_field')->justReturn('ppcp-gateway');
|
||||
when('wp_unslash')->justReturn('ppcp-gateway');
|
||||
when('current_user_can')->justReturn(true);
|
||||
when('wp_verify_nonce')->justReturn(true);
|
||||
|
||||
$settings->shouldReceive('has')
|
||||
->with('client_id')
|
||||
->andReturn('client_id');
|
||||
$settings->shouldReceive('get')
|
||||
->with('client_id')
|
||||
->andReturn('client_id');
|
||||
$settings->shouldReceive('has')
|
||||
->with('client_secret')
|
||||
->andReturn('client_secret');
|
||||
$settings->shouldReceive('get')
|
||||
->with('client_secret')
|
||||
->andReturn('client_secret');
|
||||
$settings->shouldReceive('persist');
|
||||
$cache->shouldReceive('has')
|
||||
->andReturn(false);
|
||||
|
||||
$testee->listen();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue