mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 09:08:09 +08:00
Merge branch 'trunk' into PCP-190-override-language-used-to-display-PayPal-buttons
# Conflicts: # modules/ppcp-button/services.php # modules/ppcp-button/src/Assets/SmartButton.php # modules/ppcp-wc-gateway/services.php
This commit is contained in:
commit
e3fbadf419
465 changed files with 41582 additions and 6679 deletions
|
@ -9,10 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
|
||||
use WooCommerce\WooCommerce\Logging\Logger\WooCommerceLogger;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
@ -52,43 +49,6 @@ return array(
|
|||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return $settings->has( 'prefix' ) ? (string) $settings->get( 'prefix' ) : 'WC-';
|
||||
},
|
||||
'api.endpoint.order' => static function ( ContainerInterface $container ): OrderEndpoint {
|
||||
$order_factory = $container->get( 'api.factory.order' );
|
||||
$patch_collection_factory = $container->get( 'api.factory.patch-collection-factory' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
/**
|
||||
* The session handler.
|
||||
*
|
||||
* @var SessionHandler $session_handler
|
||||
*/
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
$bn_code = $session_handler->bn_code();
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings $settings
|
||||
*/
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$intent = $settings->has( 'intent' ) && strtoupper( (string) $settings->get( 'intent' ) ) === 'AUTHORIZE' ? 'AUTHORIZE' : 'CAPTURE';
|
||||
$application_context_repository = $container->get( 'api.repository.application-context' );
|
||||
$pay_pal_request_id_repository = $container->get( 'api.repository.paypal-request-id' );
|
||||
$subscription_helper = $container->get( 'subscription.helper' );
|
||||
return new OrderEndpoint(
|
||||
$container->get( 'api.host' ),
|
||||
$container->get( 'api.bearer' ),
|
||||
$order_factory,
|
||||
$patch_collection_factory,
|
||||
$intent,
|
||||
$logger,
|
||||
$application_context_repository,
|
||||
$pay_pal_request_id_repository,
|
||||
$subscription_helper,
|
||||
$container->get( 'wcgateway.is-fraudnet-enabled' ),
|
||||
$container->get( 'wcgateway.fraudnet' ),
|
||||
$bn_code
|
||||
);
|
||||
},
|
||||
'woocommerce.logger.woocommerce' => function ( ContainerInterface $container ): LoggerInterface {
|
||||
if ( ! function_exists( 'wc_get_logger' ) || ! $container->get( 'wcgateway.logging.is-enabled' ) ) {
|
||||
return new NullLogger();
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.74",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
11
modules/ppcp-wc-gateway/resources/css/common.scss
Normal file
11
modules/ppcp-wc-gateway/resources/css/common.scss
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
.ppcp-field-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.ppcp-field-disabled {
|
||||
cursor: not-allowed;
|
||||
-webkit-filter: grayscale(100%);
|
||||
filter: grayscale(100%);
|
||||
opacity: 0.5;
|
||||
}
|
28
modules/ppcp-wc-gateway/resources/js/common.js
Normal file
28
modules/ppcp-wc-gateway/resources/js/common.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
import DisplayManager from "./common/display-manager/DisplayManager";
|
||||
import moveWrappedElements from "./common/wrapped-elements";
|
||||
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
|
||||
// Wait for current execution context to end.
|
||||
setTimeout(function () {
|
||||
moveWrappedElements();
|
||||
}, 0);
|
||||
|
||||
// Initialize DisplayManager.
|
||||
const displayManager = new DisplayManager();
|
||||
|
||||
jQuery( '*[data-ppcp-display]' ).each( (index, el) => {
|
||||
const rules = jQuery(el).data('ppcpDisplay');
|
||||
|
||||
// console.log('rules', rules);
|
||||
|
||||
for (const rule of rules) {
|
||||
displayManager.addRule(rule);
|
||||
}
|
||||
});
|
||||
|
||||
displayManager.register();
|
||||
}
|
||||
);
|
|
@ -0,0 +1,14 @@
|
|||
import ElementAction from "./action/ElementAction";
|
||||
|
||||
class ActionFactory {
|
||||
static make(actionConfig) {
|
||||
switch (actionConfig.type) {
|
||||
case 'element':
|
||||
return new ElementAction(actionConfig);
|
||||
}
|
||||
|
||||
throw new Error('[ActionFactory] Unknown action: ' + actionConfig.type);
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionFactory;
|
|
@ -0,0 +1,17 @@
|
|||
import ElementCondition from "./condition/ElementCondition";
|
||||
import BoolCondition from "./condition/BoolCondition";
|
||||
|
||||
class ConditionFactory {
|
||||
static make(conditionConfig, triggerUpdate) {
|
||||
switch (conditionConfig.type) {
|
||||
case 'element':
|
||||
return new ElementCondition(conditionConfig, triggerUpdate);
|
||||
case 'bool':
|
||||
return new BoolCondition(conditionConfig, triggerUpdate);
|
||||
}
|
||||
|
||||
throw new Error('[ConditionFactory] Unknown condition: ' + conditionConfig.type);
|
||||
}
|
||||
}
|
||||
|
||||
export default ConditionFactory;
|
|
@ -0,0 +1,32 @@
|
|||
import Rule from "./Rule";
|
||||
|
||||
class DisplayManager {
|
||||
|
||||
constructor() {
|
||||
this.rules = {};
|
||||
this.ruleStatus = {}; // The current status for each rule. Maybe not necessary, for now just for logging.
|
||||
|
||||
document.ppcpDisplayManagerLog = () => {
|
||||
console.log('DisplayManager', this);
|
||||
}
|
||||
}
|
||||
|
||||
addRule(ruleConfig) {
|
||||
const updateStatus = () => {
|
||||
this.ruleStatus[ruleConfig.key] = this.rules[ruleConfig.key].status;
|
||||
//console.log('ruleStatus', this.ruleStatus);
|
||||
}
|
||||
|
||||
this.rules[ruleConfig.key] = new Rule(ruleConfig, updateStatus.bind(this));
|
||||
//console.log('Rule', this.rules[ruleConfig.key]);
|
||||
}
|
||||
|
||||
register() {
|
||||
this.ruleStatus = {};
|
||||
for (const [key, rule] of Object.entries(this.rules)) {
|
||||
rule.register();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default DisplayManager;
|
|
@ -0,0 +1,68 @@
|
|||
import ConditionFactory from "./ConditionFactory";
|
||||
import ActionFactory from "./ActionFactory";
|
||||
|
||||
class Rule {
|
||||
|
||||
constructor(config, triggerUpdate) {
|
||||
this.config = config;
|
||||
this.conditions = {};
|
||||
this.actions = {};
|
||||
this.triggerUpdate = triggerUpdate;
|
||||
this.status = null;
|
||||
|
||||
const updateStatus = this.updateStatus.bind(this);
|
||||
for (const conditionConfig of this.config.conditions) {
|
||||
const condition = ConditionFactory.make(conditionConfig, updateStatus);
|
||||
this.conditions[condition.key] = condition;
|
||||
|
||||
//console.log('Condition', condition);
|
||||
}
|
||||
|
||||
for (const actionConfig of this.config.actions) {
|
||||
const action = ActionFactory.make(actionConfig);
|
||||
this.actions[action.key] = action;
|
||||
|
||||
//console.log('Action', action);
|
||||
}
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this.config.key;
|
||||
}
|
||||
|
||||
updateStatus(forceRunActions = false) {
|
||||
let status = true;
|
||||
|
||||
for (const [key, condition] of Object.entries(this.conditions)) {
|
||||
status &= condition.status;
|
||||
}
|
||||
|
||||
if (status !== this.status) {
|
||||
this.status = status;
|
||||
this.triggerUpdate();
|
||||
this.runActions();
|
||||
} else if (forceRunActions) {
|
||||
this.runActions();
|
||||
}
|
||||
}
|
||||
|
||||
runActions() {
|
||||
for (const [key, action] of Object.entries(this.actions)) {
|
||||
action.run(this.status);
|
||||
}
|
||||
}
|
||||
|
||||
register() {
|
||||
for (const [key, condition] of Object.entries(this.conditions)) {
|
||||
condition.register(this.updateStatus.bind(this));
|
||||
}
|
||||
for (const [key, action] of Object.entries(this.actions)) {
|
||||
action.register();
|
||||
}
|
||||
|
||||
this.updateStatus(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Rule;
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
class BaseAction {
|
||||
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this.config.key;
|
||||
}
|
||||
|
||||
register() {
|
||||
// To override.
|
||||
}
|
||||
|
||||
run(status) {
|
||||
// To override.
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseAction;
|
|
@ -0,0 +1,35 @@
|
|||
import BaseAction from "./BaseAction";
|
||||
|
||||
class ElementAction extends BaseAction {
|
||||
|
||||
run(status) {
|
||||
|
||||
if (status) {
|
||||
if (this.config.action === 'visible') {
|
||||
jQuery(this.config.selector).removeClass('ppcp-field-hidden');
|
||||
}
|
||||
if (this.config.action === 'enable') {
|
||||
jQuery(this.config.selector).removeClass('ppcp-field-disabled')
|
||||
.off('mouseup')
|
||||
.find('> *')
|
||||
.css('pointer-events', '');
|
||||
}
|
||||
} else {
|
||||
if (this.config.action === 'visible') {
|
||||
jQuery(this.config.selector).addClass('ppcp-field-hidden');
|
||||
}
|
||||
if (this.config.action === 'enable') {
|
||||
jQuery(this.config.selector).addClass('ppcp-field-disabled')
|
||||
.on('mouseup', function(event) {
|
||||
event.stopImmediatePropagation();
|
||||
})
|
||||
.find('> *')
|
||||
.css('pointer-events', 'none');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ElementAction;
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
class BaseCondition {
|
||||
|
||||
constructor(config, triggerUpdate) {
|
||||
this.config = config;
|
||||
this.status = false;
|
||||
this.triggerUpdate = triggerUpdate;
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this.config.key;
|
||||
}
|
||||
|
||||
register() {
|
||||
// To override.
|
||||
}
|
||||
}
|
||||
|
||||
export default BaseCondition;
|
|
@ -0,0 +1,15 @@
|
|||
import BaseCondition from "./BaseCondition";
|
||||
|
||||
class BoolCondition extends BaseCondition {
|
||||
|
||||
register() {
|
||||
this.status = this.check();
|
||||
}
|
||||
|
||||
check() {
|
||||
return !! this.config.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default BoolCondition;
|
|
@ -0,0 +1,27 @@
|
|||
import BaseCondition from "./BaseCondition";
|
||||
import {inputValue} from "../../../helper/form";
|
||||
|
||||
class ElementCondition extends BaseCondition {
|
||||
|
||||
register() {
|
||||
jQuery(document).on('change', this.config.selector, () => {
|
||||
const status = this.check();
|
||||
if (status !== this.status) {
|
||||
this.status = status;
|
||||
this.triggerUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
this.status = this.check();
|
||||
}
|
||||
|
||||
check() {
|
||||
let value = inputValue(this.config.selector);
|
||||
value = (value !== null ? value.toString() : value);
|
||||
|
||||
return this.config.value === value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ElementCondition;
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
// This function is needed because WordPress moves our custom notices to the global placeholder.
|
||||
function moveWrappedElements() {
|
||||
(($) => {
|
||||
$('*[data-ppcp-wrapper]').each(function() {
|
||||
let $wrapper = $('.' + $(this).data('ppcpWrapper'));
|
||||
if ($wrapper.length) {
|
||||
$wrapper.append(this);
|
||||
}
|
||||
});
|
||||
})(jQuery)
|
||||
}
|
||||
|
||||
export default moveWrappedElements;
|
|
@ -2,9 +2,10 @@ import { loadScript } from "@paypal/paypal-js";
|
|||
import {debounce} from "./helper/debounce";
|
||||
import Renderer from '../../../ppcp-button/resources/js/modules/Renderer/Renderer'
|
||||
import MessageRenderer from "../../../ppcp-button/resources/js/modules/Renderer/MessageRenderer";
|
||||
import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/modules/Helper/Hiding"
|
||||
import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/modules/Helper/Hiding";
|
||||
import widgetBuilder from "../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder";
|
||||
|
||||
;document.addEventListener(
|
||||
document.addEventListener(
|
||||
'DOMContentLoaded',
|
||||
() => {
|
||||
function disableAll(nodeList){
|
||||
|
@ -86,6 +87,7 @@ import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/mo
|
|||
|
||||
try {
|
||||
renderer.render({});
|
||||
jQuery(document).trigger('ppcp_paypal_render_preview', settings);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -112,12 +114,15 @@ import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/mo
|
|||
'client-id': PayPalCommerceGatewaySettings.client_id,
|
||||
'currency': PayPalCommerceGatewaySettings.currency,
|
||||
'integration-date': PayPalCommerceGatewaySettings.integration_date,
|
||||
'components': ['buttons', 'funding-eligibility', 'messages'],
|
||||
'components': PayPalCommerceGatewaySettings.components,
|
||||
'enable-funding': ['venmo', 'paylater'],
|
||||
'buyer-country': PayPalCommerceGatewaySettings.country,
|
||||
};
|
||||
|
||||
if(payLaterButtonPreview?.length) {
|
||||
if (PayPalCommerceGatewaySettings.environment === 'sandbox') {
|
||||
settings['buyer-country'] = PayPalCommerceGatewaySettings.country;
|
||||
}
|
||||
|
||||
if (payLaterButtonPreview?.length) {
|
||||
disabledSources = Object.keys(PayPalCommerceGatewaySettings.all_funding_sources);
|
||||
}
|
||||
|
||||
|
@ -135,6 +140,8 @@ import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/mo
|
|||
function loadPaypalScript(settings, onLoaded = () => {}) {
|
||||
loadScript(JSON.parse(JSON.stringify(settings))) // clone the object to prevent modification
|
||||
.then(paypal => {
|
||||
widgetBuilder.setPaypal(paypal);
|
||||
|
||||
document.dispatchEvent(new CustomEvent('ppcp_paypal_script_loaded'));
|
||||
|
||||
onLoaded(paypal);
|
||||
|
@ -166,11 +173,16 @@ import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/mo
|
|||
|
||||
function createMessagesPreview(settingsCallback) {
|
||||
const render = (settings) => {
|
||||
const wrapper = document.querySelector(settings.wrapper);
|
||||
let wrapper = document.querySelector(settings.wrapper);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
wrapper.innerHTML = '';
|
||||
// looks like .innerHTML = '' is not enough, PayPal somehow renders with old style
|
||||
const parent = wrapper.parentElement;
|
||||
parent.removeChild(wrapper);
|
||||
wrapper = document.createElement('div');
|
||||
wrapper.setAttribute('id', settings.wrapper.replace('#', ''));
|
||||
parent.appendChild(wrapper);
|
||||
|
||||
const messageRenderer = new MessageRenderer(settings);
|
||||
|
||||
|
@ -263,7 +275,7 @@ import {setVisibleByClass, isVisible} from "../../../ppcp-button/resources/js/mo
|
|||
}, 1000));
|
||||
|
||||
loadPaypalScript(oldScriptSettings, () => {
|
||||
const payLaterMessagingLocations = ['product', 'cart', 'checkout', 'general'];
|
||||
const payLaterMessagingLocations = ['product', 'cart', 'checkout', 'shop', 'home', 'general'];
|
||||
const paypalButtonLocations = ['product', 'cart', 'checkout', 'mini-cart', 'general'];
|
||||
|
||||
paypalButtonLocations.forEach((location) => {
|
||||
|
|
13
modules/ppcp-wc-gateway/resources/js/helper/form.js
Normal file
13
modules/ppcp-wc-gateway/resources/js/helper/form.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
export const inputValue = (element) => {
|
||||
const $el = jQuery(element);
|
||||
|
||||
if ($el.is(':checkbox') || $el.is(':radio')) {
|
||||
if ($el.is(':checked')) {
|
||||
return $el.val();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $el.val();
|
||||
}
|
||||
}
|
|
@ -11,20 +11,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PayUponInvoiceOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\ApplicationContext;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesDisclaimers;
|
||||
use WooCommerce\PayPalCommerce\Common\Pattern\SingletonDecorator;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\FeesRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\PaymentStatusOrderDetail;
|
||||
|
@ -32,29 +30,33 @@ use WooCommerce\PayPalCommerce\WcGateway\Admin\RenderAuthorizeAction;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Assets\FraudNetAssets;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Cli\SettingsCommand;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXO;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNetSessionId;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNetSourceWebsiteId;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\GatewayRepository;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXO;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PaymentSourceFactory;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\TransactionUrlProvider;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CheckoutHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DisplayManager;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\RefundFeesUpdater;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\AuthorizeOrderActionNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\GatewayWithoutPayPalAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\UnsupportedCurrencyAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
|
@ -94,7 +96,8 @@ return array(
|
|||
$environment,
|
||||
$payment_token_repository,
|
||||
$logger,
|
||||
$api_shop_country
|
||||
$api_shop_country,
|
||||
$container->get( 'api.endpoint.order' )
|
||||
);
|
||||
},
|
||||
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
||||
|
@ -145,7 +148,8 @@ return array(
|
|||
$session_handler = $container->get( 'session.handler' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$settings_status = $container->get( 'wcgateway.settings.status' );
|
||||
return new DisableGateways( $session_handler, $settings, $settings_status );
|
||||
$subscription_helper = $container->get( 'subscription.helper' );
|
||||
return new DisableGateways( $session_handler, $settings, $settings_status, $subscription_helper );
|
||||
},
|
||||
|
||||
'wcgateway.is-wc-payments-page' => static function ( ContainerInterface $container ): bool {
|
||||
|
@ -196,15 +200,33 @@ return array(
|
|||
return $ppcp_tab ? $ppcp_tab : $section;
|
||||
},
|
||||
|
||||
'wcgateway.settings' => static function ( ContainerInterface $container ): Settings {
|
||||
$default_button_locations = $container->get( 'wcgateway.button.default-locations' );
|
||||
return new Settings( $default_button_locations );
|
||||
},
|
||||
'wcgateway.settings' => SingletonDecorator::make(
|
||||
static function ( ContainerInterface $container ): Settings {
|
||||
return new Settings(
|
||||
$container->get( 'wcgateway.button.default-locations' ),
|
||||
$container->get( 'wcgateway.settings.dcc-gateway-title.default' )
|
||||
);
|
||||
}
|
||||
),
|
||||
'wcgateway.notice.connect' => static function ( ContainerInterface $container ): ConnectAdminNotice {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return new ConnectAdminNotice( $state, $settings );
|
||||
},
|
||||
'wcgateway.notice.currency-unsupported' => static function ( ContainerInterface $container ): UnsupportedCurrencyAdminNotice {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
$shop_currency = $container->get( 'api.shop.currency' );
|
||||
$supported_currencies = $container->get( 'api.supported-currencies' );
|
||||
$is_wc_gateways_list_page = $container->get( 'wcgateway.is-wc-gateways-list-page' );
|
||||
$is_ppcp_settings_page = $container->get( 'wcgateway.is-ppcp-settings-page' );
|
||||
return new UnsupportedCurrencyAdminNotice(
|
||||
$state,
|
||||
$shop_currency,
|
||||
$supported_currencies,
|
||||
$is_wc_gateways_list_page,
|
||||
$is_ppcp_settings_page
|
||||
);
|
||||
},
|
||||
'wcgateway.notice.dcc-without-paypal' => static function ( ContainerInterface $container ): GatewayWithoutPayPalAdminNotice {
|
||||
return new GatewayWithoutPayPalAdminNotice(
|
||||
CreditCardGateway::ID,
|
||||
|
@ -220,7 +242,8 @@ return array(
|
|||
$container->get( 'onboarding.state' ),
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.is-wc-payments-page' ),
|
||||
$container->get( 'wcgateway.is-ppcp-settings-page' )
|
||||
$container->get( 'wcgateway.is-ppcp-settings-page' ),
|
||||
$container->get( 'wcgateway.settings.status' )
|
||||
);
|
||||
},
|
||||
'wcgateway.notice.authorize-order-action' =>
|
||||
|
@ -230,8 +253,11 @@ return array(
|
|||
'wcgateway.settings.sections-renderer' => static function ( ContainerInterface $container ): SectionsRenderer {
|
||||
return new SectionsRenderer(
|
||||
$container->get( 'wcgateway.current-ppcp-settings-page-id' ),
|
||||
$container->get( 'wcgateway.settings.sections' ),
|
||||
$container->get( 'onboarding.state' )
|
||||
$container->get( 'onboarding.state' ),
|
||||
$container->get( 'wcgateway.helper.dcc-product-status' ),
|
||||
$container->get( 'api.helpers.dccapplies' ),
|
||||
$container->get( 'button.helper.messages-apply' ),
|
||||
$container->get( 'wcgateway.pay-upon-invoice-product-status' )
|
||||
);
|
||||
},
|
||||
'wcgateway.settings.header-renderer' => static function ( ContainerInterface $container ): HeaderRenderer {
|
||||
|
@ -240,52 +266,6 @@ return array(
|
|||
$container->get( 'wcgateway.url' )
|
||||
);
|
||||
},
|
||||
'wcgateway.settings.sections' => static function ( ContainerInterface $container ): array {
|
||||
$sections = array(
|
||||
Settings::CONNECTION_TAB_ID => __( 'Connection', 'woocommerce-paypal-payments' ),
|
||||
PayPalGateway::ID => __( 'Standard Payments', 'woocommerce-paypal-payments' ),
|
||||
Settings::PAY_LATER_TAB_ID => __( 'Pay Later', 'woocommerce-paypal-payments' ),
|
||||
CreditCardGateway::ID => __( 'Advanced Card Processing', 'woocommerce-paypal-payments' ),
|
||||
CardButtonGateway::ID => __( 'Standard Card Button', 'woocommerce-paypal-payments' ),
|
||||
OXXOGateway::ID => __( 'OXXO', 'woocommerce-paypal-payments' ),
|
||||
PayUponInvoiceGateway::ID => __( 'Pay upon Invoice', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
|
||||
// Remove for all not registered in WC gateways that cannot render anything in this case.
|
||||
$gateways = WC()->payment_gateways->payment_gateways();
|
||||
foreach ( array_diff(
|
||||
array_keys( $sections ),
|
||||
array( Settings::CONNECTION_TAB_ID, PayPalGateway::ID, CreditCardGateway::ID, Settings::PAY_LATER_TAB_ID )
|
||||
) as $id ) {
|
||||
if ( ! isset( $gateways[ $id ] ) ) {
|
||||
unset( $sections[ $id ] );
|
||||
}
|
||||
}
|
||||
|
||||
$dcc_product_status = $container->get( 'wcgateway.helper.dcc-product-status' );
|
||||
assert( $dcc_product_status instanceof DCCProductStatus );
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
assert( $dcc_applies instanceof DccApplies );
|
||||
if ( ! $dcc_product_status->dcc_is_active() || ! $dcc_applies->for_country_currency() ) {
|
||||
unset( $sections['ppcp-credit-card-gateway'] );
|
||||
}
|
||||
|
||||
$messages_apply = $container->get( 'button.helper.messages-apply' );
|
||||
assert( $messages_apply instanceof MessagesApply );
|
||||
|
||||
if ( ! $messages_apply->for_country() ) {
|
||||
unset( $sections[ Settings::PAY_LATER_TAB_ID ] );
|
||||
}
|
||||
|
||||
$pui_product_status = $container->get( 'wcgateway.pay-upon-invoice-product-status' );
|
||||
assert( $pui_product_status instanceof PayUponInvoiceProductStatus );
|
||||
|
||||
if ( ! $pui_product_status->pui_is_active() ) {
|
||||
unset( $sections[ PayUponInvoiceGateway::ID ] );
|
||||
}
|
||||
|
||||
return $sections;
|
||||
},
|
||||
'wcgateway.settings.status' => static function ( ContainerInterface $container ): SettingsStatus {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return new SettingsStatus( $settings );
|
||||
|
@ -324,6 +304,7 @@ return array(
|
|||
$signup_link_ids = $container->get( 'onboarding.signup-link-ids' );
|
||||
$pui_status_cache = $container->get( 'pui.status-cache' );
|
||||
$dcc_status_cache = $container->get( 'dcc.status-cache' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new SettingsListener(
|
||||
$settings,
|
||||
$fields,
|
||||
|
@ -335,7 +316,11 @@ return array(
|
|||
$signup_link_cache,
|
||||
$signup_link_ids,
|
||||
$pui_status_cache,
|
||||
$dcc_status_cache
|
||||
$dcc_status_cache,
|
||||
$container->get( 'http.redirector' ),
|
||||
$container->get( 'api.partner_merchant_id-production' ),
|
||||
$container->get( 'api.partner_merchant_id-sandbox' ),
|
||||
$logger
|
||||
);
|
||||
},
|
||||
'wcgateway.order-processor' => static function ( ContainerInterface $container ): OrderProcessor {
|
||||
|
@ -364,10 +349,11 @@ return array(
|
|||
);
|
||||
},
|
||||
'wcgateway.processor.refunds' => static function ( ContainerInterface $container ): RefundProcessor {
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new RefundProcessor( $order_endpoint, $payments_endpoint, $logger );
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$payments_endpoint = $container->get( 'api.endpoint.payments' );
|
||||
$refund_fees_updater = $container->get( 'wcgateway.helper.refund-fees-updater' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new RefundProcessor( $order_endpoint, $payments_endpoint, $refund_fees_updater, $logger );
|
||||
},
|
||||
'wcgateway.processor.authorized-payments' => static function ( ContainerInterface $container ): AuthorizedPaymentsProcessor {
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
|
@ -416,6 +402,28 @@ return array(
|
|||
return array_key_exists( $current_page_id, $sections );
|
||||
},
|
||||
|
||||
'wcgateway.settings.fields.subscriptions_mode' => static function ( ContainerInterface $container ): array {
|
||||
return array(
|
||||
'title' => __( 'Subscriptions Mode', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Utilize PayPal Vaulting for flexible subscription processing with saved payment methods, create “PayPal Subscriptions” to bill customers at regular intervals, or disable PayPal for subscription-type products.', 'woocommerce-paypal-payments' ),
|
||||
'default' => 'vaulting_api',
|
||||
'options' => array(
|
||||
'vaulting_api' => __( 'PayPal Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'subscriptions_api' => __( 'PayPal Subscriptions', 'woocommerce-paypal-payments' ),
|
||||
'disable_paypal_subscriptions' => __( 'Disable PayPal for subscriptions', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.settings.fields' => static function ( ContainerInterface $container ): array {
|
||||
|
||||
$should_render_settings = $container->get( 'wcgateway.settings.should-render-settings' );
|
||||
|
@ -427,8 +435,6 @@ return array(
|
|||
$state = $container->get( 'onboarding.state' );
|
||||
assert( $state instanceof State );
|
||||
|
||||
$messages_disclaimers = $container->get( 'button.helper.messages-disclaimers' );
|
||||
|
||||
$dcc_applies = $container->get( 'api.helpers.dccapplies' );
|
||||
assert( $dcc_applies instanceof DccApplies );
|
||||
|
||||
|
@ -439,7 +445,7 @@ return array(
|
|||
assert( $subscription_helper instanceof SubscriptionHelper );
|
||||
|
||||
$fields = array(
|
||||
'checkout_settings_heading' => array(
|
||||
'checkout_settings_heading' => array(
|
||||
'heading' => __( 'Standard Payments Settings', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array(
|
||||
|
@ -449,7 +455,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'title' => array(
|
||||
'title' => array(
|
||||
'title' => __( 'Title', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'description' => __(
|
||||
|
@ -465,7 +471,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'dcc_enabled' => array(
|
||||
'dcc_enabled' => array(
|
||||
'title' => __( 'Enable/Disable', 'woocommerce-paypal-payments' ),
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'Once enabled, the Credit Card option will show up in the checkout.', 'woocommerce-paypal-payments' ),
|
||||
|
@ -480,14 +486,14 @@ return array(
|
|||
State::STATE_ONBOARDED,
|
||||
),
|
||||
),
|
||||
'dcc_gateway_title' => array(
|
||||
'dcc_gateway_title' => array(
|
||||
'title' => __( 'Title', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'description' => __(
|
||||
'This controls the title which the user sees during checkout.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'default' => __( 'Credit Cards', 'woocommerce-paypal-payments' ),
|
||||
'default' => $container->get( 'wcgateway.settings.dcc-gateway-title.default' ),
|
||||
'desc_tip' => true,
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
|
@ -497,7 +503,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'description' => array(
|
||||
'description' => array(
|
||||
'title' => __( 'Description', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
|
@ -516,7 +522,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'intent' => array(
|
||||
'intent' => array(
|
||||
'title' => __( 'Intent', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
|
@ -538,7 +544,24 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'capture_for_virtual_only' => array(
|
||||
'capture_on_status_change' => array(
|
||||
'title' => __( 'Capture On Status Change', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
'desc_tip' => true,
|
||||
'description' => __(
|
||||
'The transaction will be captured automatically when the order status changes to Processing or Completed.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'label' => __( 'Capture On Status Change', 'woocommerce-paypal-payments' ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'capture_for_virtual_only' => array(
|
||||
'title' => __( 'Capture Virtual-Only Orders ', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
|
@ -555,7 +578,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'payee_preferred' => array(
|
||||
'payee_preferred' => array(
|
||||
'title' => __( 'Instant Payments ', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'default' => false,
|
||||
|
@ -572,7 +595,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'brand_name' => array(
|
||||
'brand_name' => array(
|
||||
'title' => __( 'Brand Name', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'default' => get_bloginfo( 'name' ),
|
||||
|
@ -588,12 +611,12 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'landing_page' => array(
|
||||
'landing_page' => array(
|
||||
'title' => __( 'Landing Page', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'gold',
|
||||
'default' => ApplicationContext::LANDING_PAGE_LOGIN,
|
||||
'desc_tip' => true,
|
||||
'description' => __(
|
||||
'Type of PayPal page to display.',
|
||||
|
@ -610,23 +633,15 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'disable_funding' => array(
|
||||
'title' => __( 'Hide Funding Source(s)', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => array(),
|
||||
'desc_tip' => false,
|
||||
'alternative_payment_methods' => array(
|
||||
'heading' => __( 'Alternative Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
'description' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'By default, all possible funding sources will be shown. This setting can disable funding sources such as Credit Cards, Pay Later, Venmo, or other %1$sAlternative Payment Methods%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a
|
||||
href="https://developer.paypal.com/docs/checkout/apm/"
|
||||
target="_blank"
|
||||
>',
|
||||
// translators: %1$s, %2$s, %3$s and %4$s are a link tags.
|
||||
__( '%1$sAlternative Payment Methods%2$s allow you to accept payments from customers around the globe who use their credit cards, bank accounts, wallets, and local payment methods. When a buyer pays in a currency different than yours, PayPal handles currency conversion for you and presents conversion information to the buyer during checkout.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#alternative-payment-methods" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
'options' => $container->get( 'wcgateway.all-funding-sources' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
|
@ -634,42 +649,32 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'vault_enabled' => array(
|
||||
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => $container->get( 'button.helper.vaulting-label' ),
|
||||
'description' => __( 'Allow registered buyers to save PayPal and Credit Card accounts. Allow Subscription renewals.', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'disable_funding' => array(
|
||||
'title' => __( 'Disable Alternative Payment Methods', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => array(),
|
||||
'desc_tip' => false,
|
||||
'description' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Choose to hide specific %1$sAlternative Payment Methods%2$s such as Credit Cards, Venmo, or others.', 'woocommerce-paypal-payments' ),
|
||||
'<a
|
||||
href="https://developer.paypal.com/docs/checkout/apm/"
|
||||
target="_blank"
|
||||
>',
|
||||
'</a>'
|
||||
),
|
||||
'options' => $container->get( 'wcgateway.settings.funding-sources' ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal', 'dcc' ),
|
||||
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'subscription_behavior_when_vault_fails' => array(
|
||||
'title' => __( 'Subscription capture behavior if Vault fails', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'classes' => $subscription_helper->plugin_is_active() ? array() : array( 'hide' ),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'void_auth',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'By default, subscription payments are captured only when saving the payment method was successful. Without a saved payment method, automatic renewal payments are not possible.', 'woocommerce-paypal-payments' ),
|
||||
'description_with_tip' => __( 'Determines whether authorized payments for subscription orders are captured or voided if there is no saved payment method. This only applies when the intent Capture is used for the subscription order.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'void_auth' => __( 'Void authorization & fail the order/subscription', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth' => __( 'Capture authorized payment & set subscription to Manual Renewal', 'woocommerce-paypal-payments' ),
|
||||
'capture_auth_ignore' => __( 'Capture authorized payment & disregard missing payment method', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal', 'dcc' ),
|
||||
),
|
||||
'card_billing_data_mode' => array(
|
||||
'title' => __( 'Card billing data handling', 'woocommerce-paypal-payments' ),
|
||||
'card_billing_data_mode' => array(
|
||||
'title' => __( 'Send checkout billing data to card fields', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
|
@ -688,11 +693,11 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => array( 'paypal', CardButtonGateway::ID ),
|
||||
),
|
||||
'allow_card_button_gateway' => array(
|
||||
'title' => __( 'Separate Card Button from PayPal gateway', 'woocommerce-paypal-payments' ),
|
||||
'allow_card_button_gateway' => array(
|
||||
'title' => __( 'Create gateway for Standard Card Button', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => __( 'Enable a separate payment gateway for the branded PayPal Debit or Credit Card button.', 'woocommerce-paypal-payments' ),
|
||||
'label' => __( 'Moves the Standard Card Button from the PayPal gateway into its own dedicated gateway.', 'woocommerce-paypal-payments' ),
|
||||
'description' => __( 'By default, the Debit or Credit Card button is displayed in the Standard Payments payment gateway. This setting creates a second gateway for the Card button.', 'woocommerce-paypal-payments' ),
|
||||
'default' => $container->get( 'wcgateway.settings.allow_card_button_gateway.default' ),
|
||||
'screens' => array(
|
||||
|
@ -702,8 +707,7 @@ return array(
|
|||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
|
||||
'disable_cards' => array(
|
||||
'disable_cards' => array(
|
||||
'title' => __( 'Disable specific credit cards', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
|
@ -731,7 +735,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'card_icons' => array(
|
||||
'card_icons' => array(
|
||||
'title' => __( 'Show logo of the following credit cards', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-multiselect',
|
||||
'class' => array(),
|
||||
|
@ -761,7 +765,26 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'3d_secure_heading' => array(
|
||||
'vault_enabled_dcc' => array(
|
||||
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Securely store your customers’ credit cards for a seamless checkout experience and subscription features. Payment methods are saved in the secure %1$sPayPal Vault%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#vaulting-saving-a-payment-method" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
'description' => __( 'Allow registered buyers to save Credit Card payments.', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'dcc',
|
||||
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
||||
),
|
||||
'3d_secure_heading' => array(
|
||||
'heading' => __( '3D Secure', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'description' => wp_kses_post(
|
||||
|
@ -789,7 +812,7 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'3d_secure_contingency' => array(
|
||||
'3d_secure_contingency' => array(
|
||||
'title' => __( 'Contingency for 3D Secure', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'description' => sprintf(
|
||||
|
@ -817,8 +840,52 @@ return array(
|
|||
),
|
||||
'gateway' => 'dcc',
|
||||
),
|
||||
'paypal_saved_payments' => array(
|
||||
'heading' => __( 'Saved payments', 'woocommerce-paypal-payments' ),
|
||||
'description' => sprintf(
|
||||
// translators: %1$s, %2$s, %3$s and %4$s are a link tags.
|
||||
__( 'PayPal can securely store your customers\' payment methods for %1$sfuture payments%2$s and %3$ssubscriptions%4$s, simplifying the checkout process and enabling recurring transactions on your website.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#vaulting-saving-a-payment-method" target="_blank">',
|
||||
'</a>',
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#subscriptions-faq" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
),
|
||||
'subscriptions_mode' => $container->get( 'wcgateway.settings.fields.subscriptions_mode' ),
|
||||
'vault_enabled' => array(
|
||||
'title' => __( 'Vaulting', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Securely store your customers’ PayPal accounts for a seamless checkout experience. Payment methods are saved in the secure %1$sPayPal Vault%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#vaulting-saving-a-payment-method" target="_blank">',
|
||||
'</a>'
|
||||
) . $container->get( 'button.helper.vaulting-label' ),
|
||||
'description' => __( 'Allow registered buyers to save PayPal payments.', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => 'paypal',
|
||||
'input_class' => $container->get( 'wcgateway.helper.vaulting-scope' ) ? array() : array( 'ppcp-disabled-checkbox' ),
|
||||
),
|
||||
);
|
||||
if ( ! defined( 'PPCP_FLAG_SUBSCRIPTION' ) || ! PPCP_FLAG_SUBSCRIPTION ) {
|
||||
|
||||
if ( ! $subscription_helper->plugin_is_active() ) {
|
||||
unset( $fields['subscriptions_mode'] );
|
||||
}
|
||||
|
||||
$billing_agreements_endpoint = $container->get( 'api.endpoint.billing-agreements' );
|
||||
if ( ! $billing_agreements_endpoint->reference_transaction_enabled() ) {
|
||||
unset( $fields['vault_enabled'] );
|
||||
}
|
||||
|
||||
|
@ -862,6 +929,32 @@ return array(
|
|||
'p24' => _x( 'Przelewy24', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'sofort' => _x( 'Sofort', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'venmo' => _x( 'Venmo', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'trustly' => _x( 'Trustly', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'paylater' => _x( 'Pay Later', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.extra-funding-sources' => static function( ContainerInterface $container ): array {
|
||||
return array(
|
||||
'googlepay' => _x( 'Google Pay', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
'applepay' => _x( 'Apple Pay', 'Name of payment method', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* The sources that do not cause issues about redirecting (on mobile, ...) and sometimes not returning back.
|
||||
*/
|
||||
'wcgateway.funding-sources-without-redirect' => static function( ContainerInterface $container ): array {
|
||||
return array( 'paypal', 'paylater', 'venmo', 'card' );
|
||||
},
|
||||
'wcgateway.settings.funding-sources' => static function( ContainerInterface $container ): array {
|
||||
return array_diff_key(
|
||||
$container->get( 'wcgateway.all-funding-sources' ),
|
||||
array_flip(
|
||||
array(
|
||||
'paylater',
|
||||
)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -889,11 +982,11 @@ return array(
|
|||
'wcgateway.endpoint.return-url' => static function ( ContainerInterface $container ) : ReturnUrlEndpoint {
|
||||
$gateway = $container->get( 'wcgateway.paypal-gateway' );
|
||||
$endpoint = $container->get( 'api.endpoint.order' );
|
||||
$prefix = $container->get( 'api.prefix' );
|
||||
return new ReturnUrlEndpoint(
|
||||
$gateway,
|
||||
$endpoint,
|
||||
$prefix
|
||||
$container->get( 'session.handler' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
|
||||
|
@ -905,6 +998,15 @@ return array(
|
|||
return 'https://www.paypal.com/cgi-bin/webscr?cmd=_view-a-trans&id=%s';
|
||||
},
|
||||
|
||||
'wcgateway.soft-descriptor' => static function ( ContainerInterface $container ): string {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
if ( $settings->has( 'soft_descriptor' ) ) {
|
||||
return $settings->get( 'soft_descriptor' );
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
'wcgateway.transaction-url-provider' => static function ( ContainerInterface $container ): TransactionUrlProvider {
|
||||
$sandbox_url_base = $container->get( 'wcgateway.transaction-url-sandbox' );
|
||||
$live_url_base = $container->get( 'wcgateway.transaction-url-live' );
|
||||
|
@ -920,10 +1022,18 @@ return array(
|
|||
$settings,
|
||||
$partner_endpoint,
|
||||
$container->get( 'dcc.status-cache' ),
|
||||
$container->get( 'api.helpers.dccapplies' )
|
||||
$container->get( 'api.helpers.dccapplies' ),
|
||||
$container->get( 'onboarding.state' ),
|
||||
$container->get( 'api.helper.failure-registry' )
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.helper.refund-fees-updater' => static function ( ContainerInterface $container ): RefundFeesUpdater {
|
||||
$order_endpoint = $container->get( 'api.endpoint.order' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new RefundFeesUpdater( $order_endpoint, $logger );
|
||||
},
|
||||
|
||||
'button.helper.messages-disclaimers' => static function ( ContainerInterface $container ): MessagesDisclaimers {
|
||||
return new MessagesDisclaimers(
|
||||
$container->get( 'api.shop.country' )
|
||||
|
@ -932,9 +1042,14 @@ return array(
|
|||
|
||||
'wcgateway.funding-source.renderer' => function ( ContainerInterface $container ) : FundingSourceRenderer {
|
||||
return new FundingSourceRenderer(
|
||||
$container->get( 'wcgateway.settings' )
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
array_merge(
|
||||
$container->get( 'wcgateway.all-funding-sources' ),
|
||||
$container->get( 'wcgateway.extra-funding-sources' )
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.checkout-helper' => static function ( ContainerInterface $container ): CheckoutHelper {
|
||||
return new CheckoutHelper();
|
||||
},
|
||||
|
@ -988,7 +1103,9 @@ return array(
|
|||
return new PayUponInvoiceProductStatus(
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'api.endpoint.partners' ),
|
||||
$container->get( 'pui.status-cache' )
|
||||
$container->get( 'pui.status-cache' ),
|
||||
$container->get( 'onboarding.state' ),
|
||||
$container->get( 'api.helper.failure-registry' )
|
||||
);
|
||||
},
|
||||
'wcgateway.pay-upon-invoice' => static function ( ContainerInterface $container ): PayUponInvoice {
|
||||
|
@ -1022,15 +1139,6 @@ return array(
|
|||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'wcgateway.endpoint.oxxo' => static function ( ContainerInterface $container ): OXXOEndpoint {
|
||||
return new OXXOEndpoint(
|
||||
$container->get( 'button.request-data' ),
|
||||
$container->get( 'api.endpoint.order' ),
|
||||
$container->get( 'api.factory.purchase-unit' ),
|
||||
$container->get( 'api.factory.shipping-preference' ),
|
||||
$container->get( 'woocommerce.logger.woocommerce' )
|
||||
);
|
||||
},
|
||||
'wcgateway.logging.is-enabled' => function ( ContainerInterface $container ) : bool {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
|
||||
|
@ -1053,13 +1161,7 @@ return array(
|
|||
},
|
||||
|
||||
'button.helper.vaulting-label' => static function ( ContainerInterface $container ): string {
|
||||
$vaulting_label = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Enable saved cards, PayPal accounts, and subscription features on your store. Payment methods are saved in the secure %1$sPayPal Vault%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#vaulting-saving-a-payment-method" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$vaulting_label = '';
|
||||
if ( ! $container->get( 'wcgateway.helper.vaulting-scope' ) ) {
|
||||
$vaulting_label .= sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
|
@ -1092,6 +1194,10 @@ return array(
|
|||
return $vaulting_label;
|
||||
},
|
||||
|
||||
'wcgateway.settings.dcc-gateway-title.default' => static function ( ContainerInterface $container ): string {
|
||||
return __( 'Debit & Credit Cards', 'woocommerce-paypal-payments' );
|
||||
},
|
||||
|
||||
'wcgateway.settings.card_billing_data_mode.default' => static function ( ContainerInterface $container ): string {
|
||||
return $container->get( 'api.shop.is-latin-america' ) ? CardBillingMode::MINIMAL_INPUT : CardBillingMode::USE_WC;
|
||||
},
|
||||
|
@ -1118,62 +1224,34 @@ return array(
|
|||
'wcgateway.settings.has_enabled_separate_button_gateways' => static function ( ContainerInterface $container ): bool {
|
||||
return (bool) $container->get( 'wcgateway.settings.allow_card_button_gateway' );
|
||||
},
|
||||
|
||||
'order-tracking.is-tracking-available' => static function ( ContainerInterface $container ): bool {
|
||||
try {
|
||||
$bearer = $container->get( 'api.bearer' );
|
||||
assert( $bearer instanceof Bearer );
|
||||
|
||||
$token = $bearer->bearer();
|
||||
return $token->is_tracking_available();
|
||||
} catch ( RuntimeException $exception ) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
'wcgateway.settings.should-disable-tracking-checkbox' => static function ( ContainerInterface $container ): bool {
|
||||
'wcgateway.settings.should-disable-fraudnet-checkbox' => static function( ContainerInterface $container ): bool {
|
||||
$pui_helper = $container->get( 'wcgateway.pay-upon-invoice-helper' );
|
||||
assert( $pui_helper instanceof PayUponInvoiceHelper );
|
||||
|
||||
$is_tracking_available = $container->get( 'order-tracking.is-tracking-available' );
|
||||
|
||||
if ( ! $is_tracking_available ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $pui_helper->is_pui_gateway_enabled() ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
'wcgateway.settings.tracking-label' => static function ( ContainerInterface $container ): string {
|
||||
$tracking_label = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Enable shipment tracking information to be sent to PayPal for seller protection features. Required when %1$sPay upon Invoice%2$s is used.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#pay-upon-invoice-PUI" target="_blank">',
|
||||
'wcgateway.settings.fraudnet-label' => static function ( ContainerInterface $container ): string {
|
||||
$label = sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Manage online risk with %1$sFraudNet%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#fraudnet" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
$is_tracking_available = $container->get( 'order-tracking.is-tracking-available' );
|
||||
|
||||
if ( $is_tracking_available ) {
|
||||
return $tracking_label;
|
||||
if ( 'DE' === $container->get( 'api.shop.country' ) ) {
|
||||
$label .= '<br/>' . sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Required when %1$sPay upon Invoice%2$s is used.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#pay-upon-invoice-PUI" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
}
|
||||
|
||||
$tracking_label .= sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__(
|
||||
' To use tracking features, you must %1$senable tracking on your account%2$s.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'<a
|
||||
href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/#enable-tracking-on-your-live-account"
|
||||
target="_blank"
|
||||
>',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
return $tracking_label;
|
||||
return $label;
|
||||
},
|
||||
'wcgateway.enable-dcc-url-sandbox' => static function ( ContainerInterface $container ): string {
|
||||
return 'https://www.sandbox.paypal.com/bizsignup/entry/product/ppcp';
|
||||
|
@ -1188,6 +1266,11 @@ return array(
|
|||
return 'https://www.paypal.com/bizsignup/entry?country.x=DE&product=payment_methods&capabilities=PAY_UPON_INVOICE';
|
||||
},
|
||||
'wcgateway.settings.connection.dcc-status-text' => static function ( ContainerInterface $container ): string {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
if ( $state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$dcc_product_status = $container->get( 'wcgateway.helper.dcc-product-status' );
|
||||
assert( $dcc_product_status instanceof DCCProductStatus );
|
||||
|
||||
|
@ -1196,7 +1279,7 @@ return array(
|
|||
|
||||
$dcc_enabled = $dcc_product_status->dcc_is_active();
|
||||
|
||||
$enabled_status_text = esc_html__( 'Status: Enabled', 'woocommerce-paypal-payments' );
|
||||
$enabled_status_text = esc_html__( 'Status: Available', 'woocommerce-paypal-payments' );
|
||||
$disabled_status_text = esc_html__( 'Status: Not yet enabled', 'woocommerce-paypal-payments' );
|
||||
|
||||
$dcc_button_text = $dcc_enabled
|
||||
|
@ -1221,6 +1304,11 @@ return array(
|
|||
);
|
||||
},
|
||||
'wcgateway.settings.connection.pui-status-text' => static function ( ContainerInterface $container ): string {
|
||||
$state = $container->get( 'onboarding.state' );
|
||||
if ( $state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$pui_product_status = $container->get( 'wcgateway.pay-upon-invoice-product-status' );
|
||||
assert( $pui_product_status instanceof PayUponInvoiceProductStatus );
|
||||
|
||||
|
@ -1229,7 +1317,7 @@ return array(
|
|||
|
||||
$pui_enabled = $pui_product_status->pui_is_active();
|
||||
|
||||
$enabled_status_text = esc_html__( 'Status: Enabled', 'woocommerce-paypal-payments' );
|
||||
$enabled_status_text = esc_html__( 'Status: Available', 'woocommerce-paypal-payments' );
|
||||
$disabled_status_text = esc_html__( 'Status: Not yet enabled', 'woocommerce-paypal-payments' );
|
||||
|
||||
$enable_pui_url = $environment->current_environment_is( Environment::PRODUCTION )
|
||||
|
@ -1270,7 +1358,13 @@ return array(
|
|||
'wcgateway.settings.pay-later.messaging-locations' => static function( ContainerInterface $container ): array {
|
||||
$button_locations = $container->get( 'wcgateway.button.locations' );
|
||||
unset( $button_locations['mini-cart'] );
|
||||
return $button_locations;
|
||||
return array_merge(
|
||||
$button_locations,
|
||||
array(
|
||||
'shop' => __( 'Shop', 'woocommerce-paypal-payments' ),
|
||||
'home' => __( 'Home', 'woocommerce-paypal-payments' ),
|
||||
)
|
||||
);
|
||||
},
|
||||
'wcgateway.button.default-locations' => static function( ContainerInterface $container ): array {
|
||||
return array_keys( $container->get( 'wcgateway.settings.pay-later.messaging-locations' ) );
|
||||
|
@ -1280,24 +1374,10 @@ return array(
|
|||
assert( $settings instanceof Settings );
|
||||
|
||||
$button_locations = $container->get( 'wcgateway.button.locations' );
|
||||
unset( $button_locations['mini-cart'] );
|
||||
|
||||
$smart_button_selected_locations = $settings->has( 'smart_button_locations' ) ? $settings->get( 'smart_button_locations' ) : array();
|
||||
$pay_later_button_locations = array();
|
||||
|
||||
if ( empty( $smart_button_selected_locations ) ) {
|
||||
return $pay_later_button_locations;
|
||||
}
|
||||
|
||||
foreach ( $button_locations as $location_key => $location ) {
|
||||
if ( ! in_array( $location_key, $smart_button_selected_locations, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pay_later_button_locations[ $location_key ] = $location;
|
||||
}
|
||||
|
||||
return $pay_later_button_locations;
|
||||
return array_intersect_key( $button_locations, array_flip( $smart_button_selected_locations ) );
|
||||
},
|
||||
'wcgateway.ppcp-gateways' => static function ( ContainerInterface $container ): array {
|
||||
return array(
|
||||
|
@ -1308,52 +1388,10 @@ return array(
|
|||
OXXOGateway::ID,
|
||||
);
|
||||
},
|
||||
'wcgateway.enabled-ppcp-gateways' => static function ( ContainerInterface $container ): array {
|
||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||
$ppcp_gateways = $container->get( 'wcgateway.ppcp-gateways' );
|
||||
$enabled_ppcp_gateways = array();
|
||||
|
||||
foreach ( $ppcp_gateways as $gateway ) {
|
||||
if ( ! isset( $available_gateways[ $gateway ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$enabled_ppcp_gateways[] = $gateway;
|
||||
}
|
||||
|
||||
return $enabled_ppcp_gateways;
|
||||
},
|
||||
'wcgateway.is-paypal-continuation' => static function ( ContainerInterface $container ): bool {
|
||||
$session_handler = $container->get( 'session.handler' );
|
||||
assert( $session_handler instanceof SessionHandler );
|
||||
|
||||
$order = $session_handler->order();
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
$source = $order->payment_source();
|
||||
if ( $source && $source->card() ) {
|
||||
return false; // Ignore for DCC.
|
||||
}
|
||||
if ( 'card' === $session_handler->funding_source() ) {
|
||||
return false; // Ignore for card buttons.
|
||||
}
|
||||
return true;
|
||||
},
|
||||
'wcgateway.current-context' => static function ( ContainerInterface $container ): string {
|
||||
$context = 'mini-cart';
|
||||
if ( is_product() || wc_post_content_has_shortcode( 'product_page' ) ) {
|
||||
$context = 'product';
|
||||
}
|
||||
if ( is_cart() ) {
|
||||
$context = 'cart';
|
||||
}
|
||||
if ( is_checkout() && ! $container->get( 'wcgateway.is-paypal-continuation' ) ) {
|
||||
$context = 'checkout';
|
||||
}
|
||||
if ( is_checkout_pay_page() ) {
|
||||
$context = 'pay-now';
|
||||
}
|
||||
return $context;
|
||||
'wcgateway.gateway-repository' => static function ( ContainerInterface $container ): GatewayRepository {
|
||||
return new GatewayRepository(
|
||||
$container->get( 'wcgateway.ppcp-gateways' )
|
||||
);
|
||||
},
|
||||
'wcgateway.is-fraudnet-enabled' => static function ( ContainerInterface $container ): bool {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
|
@ -1368,11 +1406,22 @@ return array(
|
|||
$container->get( 'wcgateway.fraudnet' ),
|
||||
$container->get( 'onboarding.environment' ),
|
||||
$container->get( 'wcgateway.settings' ),
|
||||
$container->get( 'wcgateway.enabled-ppcp-gateways' ),
|
||||
$container->get( 'wcgateway.current-context' ),
|
||||
$container->get( 'wcgateway.gateway-repository' ),
|
||||
$container->get( 'session.handler' ),
|
||||
$container->get( 'wcgateway.is-fraudnet-enabled' )
|
||||
);
|
||||
},
|
||||
'wcgateway.cli.settings.command' => function( ContainerInterface $container ) : SettingsCommand {
|
||||
return new SettingsCommand(
|
||||
$container->get( 'wcgateway.settings' )
|
||||
);
|
||||
},
|
||||
'wcgateway.display-manager' => SingletonDecorator::make(
|
||||
static function( ContainerInterface $container ): DisplayManager {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
return new DisplayManager( $settings );
|
||||
}
|
||||
),
|
||||
'wcgateway.wp-paypal-locales-map' => static function( ContainerInterface $container ): array {
|
||||
return array(
|
||||
'ar' => 'ar_EG',
|
||||
|
|
|
@ -24,11 +24,18 @@ class FeesRenderer {
|
|||
* @return string
|
||||
*/
|
||||
public function render( WC_Order $wc_order ) : string {
|
||||
$breakdown = $wc_order->get_meta( PayPalGateway::FEES_META_KEY );
|
||||
$breakdown = $wc_order->get_meta( PayPalGateway::FEES_META_KEY );
|
||||
$refund_breakdown = $wc_order->get_meta( PayPalGateway::REFUND_FEES_META_KEY ) ?: array();
|
||||
|
||||
if ( ! is_array( $breakdown ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$refund_fee = $refund_breakdown['paypal_fee'] ?? array();
|
||||
$refund_amount = $refund_breakdown['net_amount'] ?? array();
|
||||
$refund_total = ( $refund_fee['value'] ?? 0 ) + ( $refund_amount['value'] ?? 0 );
|
||||
$refund_currency = ( ( $refund_amount['currency_code'] ?? '' ) === ( $refund_fee['currency_code'] ?? '' ) ) ? ( $refund_amount['currency_code'] ?? '' ) : '';
|
||||
|
||||
$html = '';
|
||||
|
||||
$fee = $breakdown['paypal_fee'] ?? null;
|
||||
|
@ -42,6 +49,28 @@ class FeesRenderer {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $refund_fee ) {
|
||||
$html .= $this->render_money_row(
|
||||
__( 'PayPal Refund Fee:', 'woocommerce-paypal-payments' ),
|
||||
__( 'The fee PayPal collects for the refund transactions.', 'woocommerce-paypal-payments' ),
|
||||
$refund_fee['value'],
|
||||
$refund_fee['currency_code'],
|
||||
true,
|
||||
'refunded-total'
|
||||
);
|
||||
}
|
||||
|
||||
if ( $refund_amount ) {
|
||||
$html .= $this->render_money_row(
|
||||
__( 'PayPal Refunded:', 'woocommerce-paypal-payments' ),
|
||||
__( 'The net amount that was refunded.', 'woocommerce-paypal-payments' ),
|
||||
$refund_amount['value'],
|
||||
$refund_amount['currency_code'],
|
||||
true,
|
||||
'refunded-total'
|
||||
);
|
||||
}
|
||||
|
||||
$net = $breakdown['net_amount'] ?? null;
|
||||
if ( is_array( $net ) ) {
|
||||
$html .= $this->render_money_row(
|
||||
|
@ -50,6 +79,15 @@ class FeesRenderer {
|
|||
$net['value'],
|
||||
$net['currency_code']
|
||||
);
|
||||
|
||||
if ( ( $refund_total > 0.0 && $refund_currency === $net['currency_code'] ) ) {
|
||||
$html .= $this->render_money_row(
|
||||
__( 'PayPal Net Total:', 'woocommerce-paypal-payments' ),
|
||||
__( 'The net total that will be credited to your PayPal account minus the refunds.', 'woocommerce-paypal-payments' ),
|
||||
$net['value'] - $refund_total,
|
||||
$net['currency_code']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $html;
|
||||
|
@ -63,9 +101,10 @@ class FeesRenderer {
|
|||
* @param string|float $value The money value.
|
||||
* @param string $currency The currency code.
|
||||
* @param bool $negative Whether to add the minus sign.
|
||||
* @param string $html_class Html class to add to the elements.
|
||||
* @return string
|
||||
*/
|
||||
private function render_money_row( string $title, string $tooltip, $value, string $currency, bool $negative = false ): string {
|
||||
private function render_money_row( string $title, string $tooltip, $value, string $currency, bool $negative = false, string $html_class = '' ): string {
|
||||
/**
|
||||
* Bad type hint in WC phpdoc.
|
||||
*
|
||||
|
@ -73,10 +112,10 @@ class FeesRenderer {
|
|||
*/
|
||||
return '
|
||||
<tr>
|
||||
<td class="label">' . wc_help_tip( $tooltip ) . ' ' . esc_html( $title ) . '
|
||||
<td class="' . trim( 'label ' . $html_class ) . '">' . wc_help_tip( $tooltip ) . ' ' . esc_html( $title ) . '
|
||||
</td>
|
||||
<td width="1%"></td>
|
||||
<td class="total">
|
||||
<td class="' . trim( 'total ' . $html_class ) . '">
|
||||
' .
|
||||
( $negative ? ' - ' : '' ) .
|
||||
wc_price( $value, array( 'currency' => $currency ) ) . '
|
||||
|
|
|
@ -9,8 +9,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\GatewayRepository;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
@ -20,6 +24,8 @@ use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
|||
*/
|
||||
class FraudNetAssets {
|
||||
|
||||
use ContextTrait;
|
||||
|
||||
/**
|
||||
* The URL of this module.
|
||||
*
|
||||
|
@ -58,16 +64,23 @@ class FraudNetAssets {
|
|||
/**
|
||||
* The list of enabled PayPal gateways.
|
||||
*
|
||||
* @var string[]
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected $enabled_ppcp_gateways;
|
||||
|
||||
/**
|
||||
* The current context.
|
||||
* The GatewayRepository.
|
||||
*
|
||||
* @var string
|
||||
* @var GatewayRepository
|
||||
*/
|
||||
protected $context;
|
||||
protected $gateway_repository;
|
||||
|
||||
/**
|
||||
* The session handler
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
protected $session_handler;
|
||||
|
||||
/**
|
||||
* True if FraudNet support is enabled in settings, otherwise false.
|
||||
|
@ -79,14 +92,14 @@ class FraudNetAssets {
|
|||
/**
|
||||
* Assets constructor.
|
||||
*
|
||||
* @param string $module_url The url of this module.
|
||||
* @param string $version The assets version.
|
||||
* @param FraudNet $fraud_net The FraudNet entity.
|
||||
* @param Environment $environment The environment.
|
||||
* @param Settings $settings The Settings.
|
||||
* @param string[] $enabled_ppcp_gateways The list of enabled PayPal gateways.
|
||||
* @param string $context The current context.
|
||||
* @param bool $is_fraudnet_enabled true if FraudNet support is enabled in settings, otherwise false.
|
||||
* @param string $module_url The url of this module.
|
||||
* @param string $version The assets version.
|
||||
* @param FraudNet $fraud_net The FraudNet entity.
|
||||
* @param Environment $environment The environment.
|
||||
* @param Settings $settings The Settings.
|
||||
* @param GatewayRepository $gateway_repository The GatewayRepository.
|
||||
* @param SessionHandler $session_handler The session handler.
|
||||
* @param bool $is_fraudnet_enabled true if FraudNet support is enabled in settings, otherwise false.
|
||||
*/
|
||||
public function __construct(
|
||||
string $module_url,
|
||||
|
@ -94,18 +107,18 @@ class FraudNetAssets {
|
|||
FraudNet $fraud_net,
|
||||
Environment $environment,
|
||||
Settings $settings,
|
||||
array $enabled_ppcp_gateways,
|
||||
string $context,
|
||||
GatewayRepository $gateway_repository,
|
||||
SessionHandler $session_handler,
|
||||
bool $is_fraudnet_enabled
|
||||
) {
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->fraud_net = $fraud_net;
|
||||
$this->environment = $environment;
|
||||
$this->settings = $settings;
|
||||
$this->enabled_ppcp_gateways = $enabled_ppcp_gateways;
|
||||
$this->context = $context;
|
||||
$this->is_fraudnet_enabled = $is_fraudnet_enabled;
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
$this->fraud_net = $fraud_net;
|
||||
$this->environment = $environment;
|
||||
$this->settings = $settings;
|
||||
$this->gateway_repository = $gateway_repository;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->is_fraudnet_enabled = $is_fraudnet_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,19 +157,18 @@ class FraudNetAssets {
|
|||
* @return bool true if FraudNet script should be loaded, otherwise false.
|
||||
*/
|
||||
protected function should_load_fraudnet_script(): bool {
|
||||
if ( empty( $this->enabled_ppcp_gateways ) ) {
|
||||
if ( empty( $this->enabled_ppcp_gateways() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$is_pui_gateway_enabled = in_array( PayUponInvoiceGateway::ID, $this->enabled_ppcp_gateways, true );
|
||||
$is_only_standard_gateway_enabled = $this->enabled_ppcp_gateways === array( PayPalGateway::ID );
|
||||
$is_pui_gateway_enabled = in_array( PayUponInvoiceGateway::ID, $this->enabled_ppcp_gateways(), true );
|
||||
$is_only_standard_gateway_enabled = $this->enabled_ppcp_gateways() === array( PayPalGateway::ID );
|
||||
|
||||
if ( $this->context !== 'checkout' || $is_only_standard_gateway_enabled ) {
|
||||
if ( $this->context() !== 'checkout' || $is_only_standard_gateway_enabled ) {
|
||||
return $this->is_fraudnet_enabled && $this->are_buttons_enabled_for_context();
|
||||
}
|
||||
|
||||
return $is_pui_gateway_enabled ? true : $this->is_fraudnet_enabled;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,22 +177,35 @@ class FraudNetAssets {
|
|||
* @return bool true if enabled, otherwise false.
|
||||
*/
|
||||
protected function are_buttons_enabled_for_context() : bool {
|
||||
if ( ! in_array( PayPalGateway::ID, $this->enabled_ppcp_gateways, true ) ) {
|
||||
if ( ! in_array( PayPalGateway::ID, $this->enabled_ppcp_gateways(), true ) ) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
$button_locations = $this->settings->get( 'smart_button_locations' );
|
||||
} catch ( NotFoundException $exception ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$location_prefix = $this->context === 'checkout' ? '' : "{$this->context}_";
|
||||
$setting_name = "button_{$location_prefix}enabled";
|
||||
$buttons_enabled_for_context = $this->settings->has( $setting_name ) && $this->settings->get( $setting_name );
|
||||
|
||||
if ( $this->context === 'product' ) {
|
||||
return $buttons_enabled_for_context || $this->settings->has( 'mini-cart' ) && $this->settings->get( 'mini-cart' );
|
||||
}
|
||||
|
||||
if ( $this->context === 'pay-now' ) {
|
||||
if ( $this->context() === 'pay-now' ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $buttons_enabled_for_context;
|
||||
if ( $this->context() === 'product' ) {
|
||||
return in_array( 'product', $button_locations, true ) || in_array( 'mini-cart', $button_locations, true );
|
||||
}
|
||||
|
||||
return in_array( $this->context(), $button_locations, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns IDs of the currently enabled PPCP gateways.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
protected function enabled_ppcp_gateways(): array {
|
||||
if ( null === $this->enabled_ppcp_gateways ) {
|
||||
$this->enabled_ppcp_gateways = $this->gateway_repository->get_enabled_ppcp_gateway_ids();
|
||||
}
|
||||
return $this->enabled_ppcp_gateways;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Assets;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
|
||||
/**
|
||||
|
@ -58,6 +59,13 @@ class SettingsPageAssets {
|
|||
*/
|
||||
private $country;
|
||||
|
||||
/**
|
||||
* The environment object.
|
||||
*
|
||||
* @var Environment
|
||||
*/
|
||||
private $environment;
|
||||
|
||||
/**
|
||||
* Whether Pay Later button is enabled either for checkout, cart or product page.
|
||||
*
|
||||
|
@ -79,6 +87,13 @@ class SettingsPageAssets {
|
|||
*/
|
||||
protected $all_funding_sources;
|
||||
|
||||
/**
|
||||
* Whether it's a settings page of this plugin.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_settings_page;
|
||||
|
||||
/**
|
||||
* Assets constructor.
|
||||
*
|
||||
|
@ -88,9 +103,11 @@ class SettingsPageAssets {
|
|||
* @param string $client_id The PayPal SDK client ID.
|
||||
* @param string $currency 3-letter currency code of the shop.
|
||||
* @param string $country 2-letter country code of the shop.
|
||||
* @param Environment $environment The environment object.
|
||||
* @param bool $is_pay_later_button_enabled Whether Pay Later button is enabled either for checkout, cart or product page.
|
||||
* @param array $disabled_sources The list of disabled funding sources.
|
||||
* @param array $all_funding_sources The list of all existing funding sources.
|
||||
* @param bool $is_settings_page Whether it's a settings page of this plugin.
|
||||
*/
|
||||
public function __construct(
|
||||
string $module_url,
|
||||
|
@ -99,9 +116,11 @@ class SettingsPageAssets {
|
|||
string $client_id,
|
||||
string $currency,
|
||||
string $country,
|
||||
Environment $environment,
|
||||
bool $is_pay_later_button_enabled,
|
||||
array $disabled_sources,
|
||||
array $all_funding_sources
|
||||
array $all_funding_sources,
|
||||
bool $is_settings_page
|
||||
) {
|
||||
$this->module_url = $module_url;
|
||||
$this->version = $version;
|
||||
|
@ -109,15 +128,19 @@ class SettingsPageAssets {
|
|||
$this->client_id = $client_id;
|
||||
$this->currency = $currency;
|
||||
$this->country = $country;
|
||||
$this->environment = $environment;
|
||||
$this->is_pay_later_button_enabled = $is_pay_later_button_enabled;
|
||||
$this->disabled_sources = $disabled_sources;
|
||||
$this->all_funding_sources = $all_funding_sources;
|
||||
$this->is_settings_page = $is_settings_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register assets provided by this module.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_assets() {
|
||||
public function register_assets(): void {
|
||||
add_action(
|
||||
'admin_enqueue_scripts',
|
||||
function() {
|
||||
|
@ -125,11 +148,13 @@ class SettingsPageAssets {
|
|||
return;
|
||||
}
|
||||
|
||||
if ( ! $this->is_paypal_payment_method_page() ) {
|
||||
return;
|
||||
if ( $this->is_settings_page ) {
|
||||
$this->register_admin_assets();
|
||||
}
|
||||
|
||||
$this->register_admin_assets();
|
||||
if ( $this->is_paypal_payment_method_page() ) {
|
||||
$this->register_paypal_admin_assets();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -160,9 +185,9 @@ class SettingsPageAssets {
|
|||
}
|
||||
|
||||
/**
|
||||
* Register assets for admin pages.
|
||||
* Register assets for PayPal admin pages.
|
||||
*/
|
||||
private function register_admin_assets(): void {
|
||||
private function register_paypal_admin_assets(): void {
|
||||
wp_enqueue_style(
|
||||
'ppcp-gateway-settings',
|
||||
trailingslashit( $this->module_url ) . 'assets/css/gateway-settings.css',
|
||||
|
@ -186,16 +211,42 @@ class SettingsPageAssets {
|
|||
wp_localize_script(
|
||||
'ppcp-gateway-settings',
|
||||
'PayPalCommerceGatewaySettings',
|
||||
array(
|
||||
'is_subscriptions_plugin_active' => $this->subscription_helper->plugin_is_active(),
|
||||
'client_id' => $this->client_id,
|
||||
'currency' => $this->currency,
|
||||
'country' => $this->country,
|
||||
'integration_date' => PAYPAL_INTEGRATION_DATE,
|
||||
'is_pay_later_button_enabled' => $this->is_pay_later_button_enabled,
|
||||
'disabled_sources' => $this->disabled_sources,
|
||||
'all_funding_sources' => $this->all_funding_sources,
|
||||
apply_filters(
|
||||
'woocommerce_paypal_payments_admin_gateway_settings',
|
||||
array(
|
||||
'is_subscriptions_plugin_active' => $this->subscription_helper->plugin_is_active(),
|
||||
'client_id' => $this->client_id,
|
||||
'currency' => $this->currency,
|
||||
'country' => $this->country,
|
||||
'environment' => $this->environment->current_environment(),
|
||||
'integration_date' => PAYPAL_INTEGRATION_DATE,
|
||||
'is_pay_later_button_enabled' => $this->is_pay_later_button_enabled,
|
||||
'disabled_sources' => $this->disabled_sources,
|
||||
'all_funding_sources' => $this->all_funding_sources,
|
||||
'components' => array( 'buttons', 'funding-eligibility', 'messages' ),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register assets for PayPal admin pages.
|
||||
*/
|
||||
private function register_admin_assets(): void {
|
||||
wp_enqueue_style(
|
||||
'ppcp-admin-common',
|
||||
trailingslashit( $this->module_url ) . 'assets/css/common.css',
|
||||
array(),
|
||||
$this->version
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'ppcp-admin-common',
|
||||
trailingslashit( $this->module_url ) . 'assets/js/common.js',
|
||||
array(),
|
||||
$this->version,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ class CheckoutPayPalAddressPreset {
|
|||
}
|
||||
|
||||
$shipping = null;
|
||||
foreach ( $this->session_handler->order()->purchase_units() as $unit ) {
|
||||
foreach ( $order->purchase_units() as $unit ) {
|
||||
$shipping = $unit->shipping();
|
||||
if ( $shipping ) {
|
||||
break;
|
||||
|
|
|
@ -9,7 +9,9 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Checkout;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\ContextTrait;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
@ -20,6 +22,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
|||
* Class DisableGateways
|
||||
*/
|
||||
class DisableGateways {
|
||||
use ContextTrait;
|
||||
|
||||
/**
|
||||
* The Session Handler.
|
||||
|
@ -42,22 +45,32 @@ class DisableGateways {
|
|||
*/
|
||||
protected $settings_status;
|
||||
|
||||
/**
|
||||
* The subscription helper.
|
||||
*
|
||||
* @var SubscriptionHelper
|
||||
*/
|
||||
private $subscription_helper;
|
||||
|
||||
/**
|
||||
* DisableGateways constructor.
|
||||
*
|
||||
* @param SessionHandler $session_handler The Session Handler.
|
||||
* @param ContainerInterface $settings The Settings.
|
||||
* @param SettingsStatus $settings_status The Settings status helper.
|
||||
* @param SubscriptionHelper $subscription_helper The subscription helper.
|
||||
*/
|
||||
public function __construct(
|
||||
SessionHandler $session_handler,
|
||||
ContainerInterface $settings,
|
||||
SettingsStatus $settings_status
|
||||
SettingsStatus $settings_status,
|
||||
SubscriptionHelper $subscription_helper
|
||||
) {
|
||||
|
||||
$this->session_handler = $session_handler;
|
||||
$this->settings = $settings;
|
||||
$this->settings_status = $settings_status;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->settings = $settings;
|
||||
$this->settings_status = $settings_status;
|
||||
$this->subscription_helper = $subscription_helper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,8 +95,11 @@ class DisableGateways {
|
|||
unset( $methods[ CreditCardGateway::ID ] );
|
||||
}
|
||||
|
||||
if ( ! $this->settings_status->is_smart_button_enabled_for_location( 'checkout' ) && ! $this->session_handler->order() && is_checkout() ) {
|
||||
unset( $methods[ PayPalGateway::ID ] );
|
||||
if ( ! $this->settings_status->is_smart_button_enabled_for_location( 'checkout' ) ) {
|
||||
unset( $methods[ CardButtonGateway::ID ] );
|
||||
if ( ! $this->session_handler->order() && is_checkout() ) {
|
||||
unset( $methods[ PayPalGateway::ID ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $this->needs_to_disable_gateways() ) {
|
||||
|
@ -99,6 +115,10 @@ class DisableGateways {
|
|||
* @return bool
|
||||
*/
|
||||
private function disable_all_gateways() : bool {
|
||||
if ( is_null( WC()->payment_gateways ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
|
||||
if ( PayPalGateway::ID === $gateway->id && $gateway->enabled !== 'yes' ) {
|
||||
return true;
|
||||
|
@ -120,20 +140,6 @@ class DisableGateways {
|
|||
* @return bool
|
||||
*/
|
||||
private function needs_to_disable_gateways(): bool {
|
||||
$order = $this->session_handler->order();
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$source = $order->payment_source();
|
||||
if ( $source && $source->card() ) {
|
||||
return false; // DCC.
|
||||
}
|
||||
|
||||
if ( 'card' === $this->session_handler->funding_source() ) {
|
||||
return false; // Card buttons.
|
||||
}
|
||||
|
||||
return true;
|
||||
return $this->is_paypal_continuation();
|
||||
}
|
||||
}
|
||||
|
|
70
modules/ppcp-wc-gateway/src/Cli/SettingsCommand.php
Normal file
70
modules/ppcp-wc-gateway/src/Cli/SettingsCommand.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* WP-CLI commands for managing plugin settings.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Cli
|
||||
*/
|
||||
|
||||
declare( strict_types=1 );
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Cli;
|
||||
|
||||
use WP_CLI;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* Class SettingsCommand.
|
||||
*/
|
||||
class SettingsCommand {
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* SettingsCommand constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
*/
|
||||
public function __construct( Settings $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the specified settings.
|
||||
*
|
||||
* ## OPTIONS
|
||||
*
|
||||
* <id>
|
||||
* : The setting key.
|
||||
*
|
||||
* <value>
|
||||
* : The setting value.
|
||||
*
|
||||
* ## EXAMPLES
|
||||
*
|
||||
* wp pcp settings update description "Pay via PayPal."
|
||||
* wp pcp settings update vault_enabled true
|
||||
* wp pcp settings update vault_enabled false
|
||||
*
|
||||
* @param array $args Positional args.
|
||||
* @param array $assoc_args Option args.
|
||||
*/
|
||||
public function update( array $args, array $assoc_args ): void {
|
||||
$key = (string) $args[0];
|
||||
$value = $args[1];
|
||||
|
||||
if ( 'true' === strtolower( $value ) ) {
|
||||
$value = true;
|
||||
} elseif ( 'false' === strtolower( $value ) ) {
|
||||
$value = false;
|
||||
}
|
||||
|
||||
$this->settings->set( $key, $value );
|
||||
$this->settings->persist();
|
||||
|
||||
WP_CLI::success( "Updated '{$key}' to '{$value}'." );
|
||||
}
|
||||
}
|
|
@ -9,17 +9,18 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Endpoint;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\Handler\PrefixTrait;
|
||||
|
||||
/**
|
||||
* Class ReturnUrlEndpoint
|
||||
*/
|
||||
class ReturnUrlEndpoint {
|
||||
|
||||
use PrefixTrait;
|
||||
const ENDPOINT = 'ppc-return-url';
|
||||
|
||||
/**
|
||||
|
@ -36,17 +37,38 @@ class ReturnUrlEndpoint {
|
|||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* The session handler
|
||||
*
|
||||
* @var SessionHandler
|
||||
*/
|
||||
protected $session_handler;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* ReturnUrlEndpoint constructor.
|
||||
*
|
||||
* @param PayPalGateway $gateway The PayPal Gateway.
|
||||
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||
* @param string $prefix The prefix.
|
||||
* @param PayPalGateway $gateway The PayPal Gateway.
|
||||
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||
* @param SessionHandler $session_handler The session handler.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct( PayPalGateway $gateway, OrderEndpoint $order_endpoint, string $prefix ) {
|
||||
$this->gateway = $gateway;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->prefix = $prefix;
|
||||
public function __construct(
|
||||
PayPalGateway $gateway,
|
||||
OrderEndpoint $order_endpoint,
|
||||
SessionHandler $session_handler,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->gateway = $gateway;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->session_handler = $session_handler;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,13 +85,25 @@ class ReturnUrlEndpoint {
|
|||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
$order = $this->order_endpoint->order( $token );
|
||||
|
||||
$wc_order_id = $this->sanitize_custom_id( $order->purchase_units()[0]->custom_id() );
|
||||
$wc_order_id = (int) $order->purchase_units()[0]->custom_id();
|
||||
if ( ! $wc_order_id ) {
|
||||
// We cannot finish processing here without WC order, but at least go into the continuation mode.
|
||||
if ( $order->status()->is( OrderStatus::APPROVED )
|
||||
|| $order->status()->is( OrderStatus::COMPLETED )
|
||||
) {
|
||||
$this->session_handler->replace_order( $order );
|
||||
|
||||
wp_safe_redirect( wc_get_checkout_url() );
|
||||
exit();
|
||||
}
|
||||
|
||||
$this->logger->warning( "Return URL endpoint $token: no WC order ID." );
|
||||
exit();
|
||||
}
|
||||
|
||||
$wc_order = wc_get_order( $wc_order_id );
|
||||
if ( ! is_a( $wc_order, \WC_Order::class ) ) {
|
||||
$this->logger->warning( "Return URL endpoint $token: WC order $wc_order_id not found." );
|
||||
exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,13 +22,32 @@ class FundingSourceRenderer {
|
|||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Map funding source ID -> human-readable name.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $funding_sources;
|
||||
|
||||
/**
|
||||
* The IDs of the sources belonging to PayPal that do not need to mention "via PayPal".
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $own_funding_sources = array( 'venmo', 'paylater' );
|
||||
|
||||
/**
|
||||
* FundingSourceRenderer constructor.
|
||||
*
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param array<string, string> $funding_sources Map funding source ID -> human-readable name.
|
||||
*/
|
||||
public function __construct( ContainerInterface $settings ) {
|
||||
$this->settings = $settings;
|
||||
public function __construct(
|
||||
ContainerInterface $settings,
|
||||
array $funding_sources
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->funding_sources = $funding_sources;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,9 +56,17 @@ class FundingSourceRenderer {
|
|||
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||
*/
|
||||
public function render_name( string $id ): string {
|
||||
if ( 'venmo' === $id ) {
|
||||
return __( 'Venmo', 'woocommerce-paypal-payments' );
|
||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||
if ( in_array( $id, $this->own_funding_sources, true ) ) {
|
||||
return $this->funding_sources[ $id ];
|
||||
}
|
||||
return sprintf(
|
||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
||||
__( '%s (via PayPal)', 'woocommerce-paypal-payments' ),
|
||||
$this->funding_sources[ $id ]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->settings->has( 'title' ) ?
|
||||
$this->settings->get( 'title' )
|
||||
: __( 'PayPal', 'woocommerce-paypal-payments' );
|
||||
|
@ -51,9 +78,14 @@ class FundingSourceRenderer {
|
|||
* @param string $id The ID of the funding source, such as 'venmo'.
|
||||
*/
|
||||
public function render_description( string $id ): string {
|
||||
if ( 'venmo' === $id ) {
|
||||
return __( 'Pay via Venmo.', 'woocommerce-paypal-payments' );
|
||||
if ( array_key_exists( $id, $this->funding_sources ) ) {
|
||||
return sprintf(
|
||||
/* translators: %s - Sofort, BLIK, iDeal, Mercado Pago, etc. */
|
||||
__( 'Pay via %s.', 'woocommerce-paypal-payments' ),
|
||||
$this->funding_sources[ $id ]
|
||||
);
|
||||
}
|
||||
|
||||
return $this->settings->has( 'description' ) ?
|
||||
$this->settings->get( 'description' )
|
||||
: __( 'Pay via PayPal.', 'woocommerce-paypal-payments' );
|
||||
|
|
|
@ -171,18 +171,17 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
$this->payment_token_repository = $payment_token_repository;
|
||||
$this->logger = $logger;
|
||||
|
||||
if ( $this->onboarded ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
}
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
);
|
||||
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
&& $this->gateways_enabled()
|
||||
&& $this->vault_setting_enabled()
|
||||
( $this->config->has( 'vault_enabled' ) && $this->config->get( 'vault_enabled' ) )
|
||||
|| ( $this->config->has( 'subscriptions_mode' ) && $this->config->get( 'subscriptions_mode' ) === 'subscriptions_api' )
|
||||
) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
array_push(
|
||||
$this->supports,
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
|
@ -192,7 +191,7 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
'multiple_subscriptions'
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -304,9 +303,7 @@ class CardButtonGateway extends \WC_Payment_Gateway {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
|
|
@ -174,26 +174,27 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
if ( $state->current_state() === State::STATE_ONBOARDED ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
}
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
&& $this->gateways_enabled()
|
||||
&& $this->vault_setting_enabled()
|
||||
) {
|
||||
if ( $this->config->has( 'dcc_enabled' ) && $this->config->get( 'dcc_enabled' ) ) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
);
|
||||
|
||||
if ( $this->config->has( 'vault_enabled_dcc' ) && $this->config->get( 'vault_enabled_dcc' ) ) {
|
||||
array_push(
|
||||
$this->supports,
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->method_title = __(
|
||||
|
@ -395,9 +396,7 @@ class CreditCardGateway extends \WC_Payment_Gateway_CC {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
|
57
modules/ppcp-wc-gateway/src/Gateway/GatewayRepository.php
Normal file
57
modules/ppcp-wc-gateway/src/Gateway/GatewayRepository.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
/**
|
||||
* Operations with the WC gateways.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
||||
|
||||
/**
|
||||
* Class GatewayRepository
|
||||
*/
|
||||
class GatewayRepository {
|
||||
/**
|
||||
* IDs of our gateways.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $ppcp_gateway_ids;
|
||||
|
||||
/**
|
||||
* GatewayRepository constructor.
|
||||
*
|
||||
* @param string[] $ppcp_gateway_ids IDs of our gateways.
|
||||
*/
|
||||
public function __construct( array $ppcp_gateway_ids ) {
|
||||
$this->ppcp_gateway_ids = $ppcp_gateway_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns IDs of the currently enabled PPCP gateways.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_enabled_ppcp_gateway_ids(): array {
|
||||
$available_gateways = WC()->payment_gateways->get_available_payment_gateways();
|
||||
|
||||
return array_filter(
|
||||
$this->ppcp_gateway_ids,
|
||||
function ( string $id ) use ( $available_gateways ): bool {
|
||||
return isset( $available_gateways[ $id ] );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if a given gateway ID is registered.
|
||||
*
|
||||
* @param string $gateway_id The gateway ID.
|
||||
* @return bool
|
||||
*/
|
||||
public function exists( string $gateway_id ): bool {
|
||||
return in_array( $gateway_id, $this->ppcp_gateway_ids, true );
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO;
|
||||
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CheckoutHelper;
|
||||
|
||||
|
@ -63,7 +64,15 @@ class OXXO {
|
|||
|
||||
add_filter(
|
||||
'woocommerce_available_payment_gateways',
|
||||
function ( array $methods ): array {
|
||||
/**
|
||||
* Param types removed to avoid third-party issues.
|
||||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function ( $methods ) {
|
||||
if ( ! is_array( $methods ) ) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if ( ! $this->checkout_allowed_for_oxxo() ) {
|
||||
unset( $methods[ OXXOGateway::ID ] );
|
||||
|
@ -146,9 +155,19 @@ class OXXO {
|
|||
add_action(
|
||||
'add_meta_boxes',
|
||||
function( string $post_type ) {
|
||||
if ( $post_type === 'shop_order' ) {
|
||||
/**
|
||||
* Class and function exist in WooCommerce.
|
||||
*
|
||||
* @psalm-suppress UndefinedClass
|
||||
* @psalm-suppress UndefinedFunction
|
||||
*/
|
||||
$screen = class_exists( CustomOrdersTableController::class ) && wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled()
|
||||
? wc_get_page_screen_id( 'shop-order' )
|
||||
: 'shop_order';
|
||||
|
||||
if ( $post_type === $screen ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$post_id = wc_clean( wp_unslash( $_GET['post'] ?? '' ) );
|
||||
$post_id = wc_clean( wp_unslash( $_GET['id'] ?? $_GET['post'] ?? '' ) );
|
||||
$order = wc_get_order( $post_id );
|
||||
if ( is_a( $order, WC_Order::class ) && $order->get_payment_method() === OXXOGateway::ID ) {
|
||||
$payer_action = $order->get_meta( 'ppcp_oxxo_payer_action' );
|
||||
|
@ -159,7 +178,7 @@ class OXXO {
|
|||
function() use ( $payer_action ) {
|
||||
echo '<p><a class="button" href="' . esc_url( $payer_action ) . '" target="_blank">' . esc_html__( 'See OXXO voucher', 'woocommerce-paypal-payments' ) . '</a></p>';
|
||||
},
|
||||
$post_type,
|
||||
$screen,
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
|
@ -220,24 +239,5 @@ class OXXO {
|
|||
true
|
||||
);
|
||||
}
|
||||
|
||||
wp_localize_script(
|
||||
'ppcp-oxxo',
|
||||
'OXXOConfig',
|
||||
array(
|
||||
'oxxo_endpoint' => \WC_AJAX::get_endpoint( 'ppc-oxxo' ),
|
||||
'oxxo_nonce' => wp_create_nonce( 'ppc-oxxo' ),
|
||||
'error' => array(
|
||||
'generic' => __(
|
||||
'Something went wrong. Please try again or choose another payment source.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'js_validation' => __(
|
||||
'Required form fields are not filled or invalid.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Handles OXXO payer action.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Onboarding\Endpoint
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
|
||||
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
|
||||
|
||||
/**
|
||||
* OXXOEndpoint constructor.
|
||||
*/
|
||||
class OXXOEndpoint implements EndpointInterface {
|
||||
|
||||
|
||||
/**
|
||||
* The request data
|
||||
*
|
||||
* @var RequestData
|
||||
*/
|
||||
protected $request_data;
|
||||
|
||||
/**
|
||||
* The purchase unit factory.
|
||||
*
|
||||
* @var PurchaseUnitFactory
|
||||
*/
|
||||
protected $purchase_unit_factory;
|
||||
|
||||
/**
|
||||
* The shipping preference factory.
|
||||
*
|
||||
* @var ShippingPreferenceFactory
|
||||
*/
|
||||
protected $shipping_preference_factory;
|
||||
|
||||
/**
|
||||
* The order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
protected $order_endpoint;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* OXXOEndpoint constructor
|
||||
*
|
||||
* @param RequestData $request_data The request data.
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
|
||||
* @param ShippingPreferenceFactory $shipping_preference_factory The shipping preference factory.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
RequestData $request_data,
|
||||
OrderEndpoint $order_endpoint,
|
||||
PurchaseUnitFactory $purchase_unit_factory,
|
||||
ShippingPreferenceFactory $shipping_preference_factory,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->request_data = $request_data;
|
||||
$this->purchase_unit_factory = $purchase_unit_factory;
|
||||
$this->shipping_preference_factory = $shipping_preference_factory;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* The nonce
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function nonce(): string {
|
||||
return 'ppc-oxxo';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function handle_request(): bool {
|
||||
$purchase_unit = $this->purchase_unit_factory->from_wc_cart();
|
||||
$payer_action = '';
|
||||
|
||||
try {
|
||||
$shipping_preference = $this->shipping_preference_factory->from_state(
|
||||
$purchase_unit,
|
||||
'checkout'
|
||||
);
|
||||
|
||||
$order = $this->order_endpoint->create( array( $purchase_unit ), $shipping_preference );
|
||||
|
||||
$payment_source = array(
|
||||
'oxxo' => array(
|
||||
'name' => 'John Doe',
|
||||
'email' => 'foo@bar.com',
|
||||
'country_code' => 'MX',
|
||||
),
|
||||
);
|
||||
|
||||
$payment_method = $this->order_endpoint->confirm_payment_source( $order->id(), $payment_source );
|
||||
|
||||
foreach ( $payment_method->links as $link ) {
|
||||
if ( $link->rel === 'payer-action' ) {
|
||||
$payer_action = $link->href;
|
||||
}
|
||||
}
|
||||
} catch ( RuntimeException $exception ) {
|
||||
$error = $exception->getMessage();
|
||||
|
||||
if ( is_a( $exception, PayPalApiException::class ) && is_array( $exception->details() ) ) {
|
||||
$details = '';
|
||||
foreach ( $exception->details() as $detail ) {
|
||||
$issue = $detail->issue ?? '';
|
||||
$field = $detail->field ?? '';
|
||||
$description = $detail->description ?? '';
|
||||
$details .= $issue . ' ' . $field . ' ' . $description . '<br>';
|
||||
}
|
||||
|
||||
$error = $details;
|
||||
}
|
||||
|
||||
$this->logger->error( $error );
|
||||
wc_add_notice( $error, 'error' );
|
||||
|
||||
wp_send_json_error( 'Could not get OXXO payer action.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
WC()->session->set( 'ppcp_payer_action', $payer_action );
|
||||
|
||||
wp_send_json_success(
|
||||
array( 'payer_action' => $payer_action )
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,8 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway;
|
|||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentToken;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
|
@ -24,8 +26,11 @@ use WooCommerce\PayPalCommerce\Vaulting\PaymentTokenRepository;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FundingSource\FundingSourceRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\PaymentsStatusHandlingTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\RefundProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SettingsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
@ -35,7 +40,7 @@ use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
|||
*/
|
||||
class PayPalGateway extends \WC_Payment_Gateway {
|
||||
|
||||
use ProcessPaymentTrait, FreeTrialHandlerTrait, GatewaySettingsRendererTrait;
|
||||
use ProcessPaymentTrait, FreeTrialHandlerTrait, GatewaySettingsRendererTrait, OrderMetaTrait, TransactionIdHandlingTrait, PaymentsStatusHandlingTrait;
|
||||
|
||||
const ID = 'ppcp-gateway';
|
||||
const INTENT_META_KEY = '_ppcp_paypal_intent';
|
||||
|
@ -43,6 +48,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
||||
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
||||
const FEES_META_KEY = '_ppcp_paypal_fees';
|
||||
const REFUND_FEES_META_KEY = '_ppcp_paypal_refund_fees';
|
||||
const REFUNDS_META_KEY = '_ppcp_refunds';
|
||||
|
||||
/**
|
||||
|
@ -150,6 +156,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
*/
|
||||
protected $api_shop_country;
|
||||
|
||||
/**
|
||||
* The order endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* PayPalGateway constructor.
|
||||
*
|
||||
|
@ -165,8 +178,9 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param Environment $environment The environment.
|
||||
* @param PaymentTokenRepository $payment_token_repository The payment token repository.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param string $api_shop_country The api shop country.
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
*/
|
||||
public function __construct(
|
||||
SettingsRenderer $settings_renderer,
|
||||
|
@ -182,7 +196,8 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
Environment $environment,
|
||||
PaymentTokenRepository $payment_token_repository,
|
||||
LoggerInterface $logger,
|
||||
string $api_shop_country
|
||||
string $api_shop_country,
|
||||
OrderEndpoint $order_endpoint
|
||||
) {
|
||||
$this->id = self::ID;
|
||||
$this->settings_renderer = $settings_renderer;
|
||||
|
@ -202,28 +217,35 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
$this->api_shop_country = $api_shop_country;
|
||||
|
||||
if ( $this->onboarded ) {
|
||||
$this->supports = array( 'refunds' );
|
||||
$this->supports = array( 'refunds', 'tokenization' );
|
||||
}
|
||||
if (
|
||||
defined( 'PPCP_FLAG_SUBSCRIPTION' )
|
||||
&& PPCP_FLAG_SUBSCRIPTION
|
||||
&& $this->gateways_enabled()
|
||||
&& $this->vault_setting_enabled()
|
||||
) {
|
||||
if ( $this->config->has( 'enabled' ) && $this->config->get( 'enabled' ) ) {
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions',
|
||||
);
|
||||
|
||||
if (
|
||||
( $this->config->has( 'vault_enabled' ) && $this->config->get( 'vault_enabled' ) )
|
||||
|| ( $this->config->has( 'subscriptions_mode' ) && $this->config->get( 'subscriptions_mode' ) === 'subscriptions_api' )
|
||||
) {
|
||||
array_push(
|
||||
$this->supports,
|
||||
'tokenization',
|
||||
'subscriptions',
|
||||
'subscription_cancellation',
|
||||
'subscription_suspension',
|
||||
'subscription_reactivation',
|
||||
'subscription_amount_changes',
|
||||
'subscription_date_changes',
|
||||
'subscription_payment_method_change',
|
||||
'subscription_payment_method_change_customer',
|
||||
'subscription_payment_method_change_admin',
|
||||
'multiple_subscriptions'
|
||||
);
|
||||
} elseif ( $this->config->has( 'vault_enabled_dcc' ) && $this->config->get( 'vault_enabled_dcc' ) ) {
|
||||
$this->supports[] = 'tokenization';
|
||||
}
|
||||
}
|
||||
|
||||
$this->method_title = $this->define_method_title();
|
||||
|
@ -235,8 +257,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
|
||||
$funding_source = $this->session_handler->funding_source();
|
||||
if ( $funding_source ) {
|
||||
$this->title = $this->funding_source_renderer->render_name( $funding_source );
|
||||
$this->description = $this->funding_source_renderer->render_description( $funding_source );
|
||||
$order = $this->session_handler->order();
|
||||
if ( $order &&
|
||||
( $order->status()->is( OrderStatus::APPROVED ) || $order->status()->is( OrderStatus::COMPLETED ) )
|
||||
) {
|
||||
$this->title = $this->funding_source_renderer->render_name( $funding_source );
|
||||
$this->description = $this->funding_source_renderer->render_description( $funding_source );
|
||||
}
|
||||
}
|
||||
|
||||
$this->init_form_fields();
|
||||
|
@ -249,6 +276,31 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
'process_admin_options',
|
||||
)
|
||||
);
|
||||
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the gateway's title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( is_admin() ) {
|
||||
// $theorder and other things for retrieving the order or post info are not available
|
||||
// in the constructor, so must do it here.
|
||||
global $theorder;
|
||||
if ( $theorder instanceof WC_Order ) {
|
||||
if ( $theorder->get_payment_method() === self::ID ) {
|
||||
$payment_method_title = $theorder->get_payment_method_title();
|
||||
if ( $payment_method_title ) {
|
||||
$this->title = $payment_method_title;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::get_title();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -424,7 +476,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Missing
|
||||
$funding_source = wc_clean( wp_unslash( $_POST['ppcp-funding-source'] ?? '' ) );
|
||||
$funding_source = wc_clean( wp_unslash( $_POST['ppcp-funding-source'] ?? ( $_POST['funding_source'] ?? '' ) ) );
|
||||
|
||||
if ( $funding_source ) {
|
||||
$wc_order->set_payment_method_title( $this->funding_source_renderer->render_name( $funding_source ) );
|
||||
$wc_order->save();
|
||||
}
|
||||
|
||||
if ( 'card' !== $funding_source && $this->is_free_trial_order( $wc_order ) ) {
|
||||
$user_id = (int) $wc_order->get_customer_id();
|
||||
$tokens = $this->payment_token_repository->all_for_user_id( $user_id );
|
||||
|
@ -466,6 +524,29 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
//phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
try {
|
||||
$paypal_subscription_id = WC()->session->get( 'ppcp_subscription_id' ) ?? '';
|
||||
if ( $paypal_subscription_id ) {
|
||||
$order = $this->session_handler->order();
|
||||
$this->add_paypal_meta( $wc_order, $order, $this->environment );
|
||||
|
||||
$subscriptions = function_exists( 'wcs_get_subscriptions_for_order' ) ? wcs_get_subscriptions_for_order( $order_id ) : array();
|
||||
foreach ( $subscriptions as $subscription ) {
|
||||
$subscription->update_meta_data( 'ppcp_subscription', $paypal_subscription_id );
|
||||
$subscription->save();
|
||||
|
||||
$subscription->add_order_note( "PayPal subscription {$paypal_subscription_id} added." );
|
||||
}
|
||||
|
||||
$transaction_id = $this->get_paypal_order_transaction_id( $order );
|
||||
if ( $transaction_id ) {
|
||||
$this->update_transaction_id( $transaction_id, $wc_order );
|
||||
}
|
||||
|
||||
$wc_order->payment_complete();
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
}
|
||||
|
||||
if ( ! $this->order_processor->process( $wc_order ) ) {
|
||||
return $this->handle_payment_failure(
|
||||
$wc_order,
|
||||
|
@ -475,9 +556,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
);
|
||||
}
|
||||
|
||||
if ( $this->subscription_helper->has_subscription( $order_id ) ) {
|
||||
$this->schedule_saved_payment_check( $order_id, $wc_order->get_customer_id() );
|
||||
}
|
||||
do_action( 'woocommerce_paypal_payments_before_handle_payment_success', $wc_order );
|
||||
|
||||
return $this->handle_payment_success( $wc_order );
|
||||
} catch ( PayPalApiException $error ) {
|
||||
|
@ -485,12 +564,15 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
|||
'INSTRUMENT_DECLINED' => __( 'Instrument declined.', 'woocommerce-paypal-payments' ),
|
||||
'PAYER_ACTION_REQUIRED' => __( 'Payer action required, possibly overcharge.', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
$retry_errors = array_filter(
|
||||
array_keys( $retry_keys_messages ),
|
||||
function ( string $key ) use ( $error ): bool {
|
||||
return $error->has_detail( $key );
|
||||
}
|
||||
$retry_errors = array_values(
|
||||
array_filter(
|
||||
array_keys( $retry_keys_messages ),
|
||||
function ( string $key ) use ( $error ): bool {
|
||||
return $error->has_detail( $key );
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
if ( $retry_errors ) {
|
||||
$retry_error_key = $retry_errors[0];
|
||||
|
||||
|
|
|
@ -9,15 +9,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
|
||||
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Email;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PayUponInvoiceOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\CaptureFactory;
|
||||
use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CheckoutHelper;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceHelper;
|
||||
|
@ -139,6 +137,25 @@ class PayUponInvoice {
|
|||
* @throws NotFoundException When setting is not found.
|
||||
*/
|
||||
public function init(): void {
|
||||
if ( $this->pui_helper->is_pui_gateway_enabled() ) {
|
||||
$this->settings->set( 'fraudnet_enabled', true );
|
||||
$this->settings->persist();
|
||||
}
|
||||
|
||||
add_filter(
|
||||
'ppcp_partner_referrals_option',
|
||||
function ( array $option ): array {
|
||||
if ( $option['valid'] ) {
|
||||
return $option;
|
||||
}
|
||||
if ( $option['field'] === 'ppcp-onboarding-pui' ) {
|
||||
$option['valid'] = true;
|
||||
$option['value'] = ( $option['value'] ? '1' : '' );
|
||||
}
|
||||
return $option;
|
||||
}
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'ppcp_partner_referrals_data',
|
||||
function ( array $data ): array {
|
||||
|
@ -417,16 +434,27 @@ class PayUponInvoice {
|
|||
*
|
||||
* @psalm-suppress MissingClosureParamType
|
||||
*/
|
||||
function ( $methods ): array {
|
||||
if ( ! is_array( $methods ) || State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
||||
function ( $methods ) {
|
||||
if (
|
||||
! is_array( $methods )
|
||||
|| State::STATE_ONBOARDED !== $this->state->current_state()
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
|| ! ( is_checkout() || isset( $_GET['pay_for_order'] ) && $_GET['pay_for_order'] === 'true' )
|
||||
) {
|
||||
return $methods;
|
||||
}
|
||||
|
||||
if (
|
||||
! $this->pui_product_status->pui_is_active()
|
||||
|| ! $this->pui_helper->is_checkout_ready_for_pui()
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
|| ( isset( $_GET['pay_for_order'] ) && $_GET['pay_for_order'] === 'true' && ! $this->pui_helper->is_pay_for_order_ready_for_pui() )
|
||||
) {
|
||||
unset( $methods[ PayUponInvoiceGateway::ID ] );
|
||||
}
|
||||
|
||||
if (
|
||||
// phpcs:ignore WordPress.Security.NonceVerification
|
||||
isset( $_GET['pay_for_order'] ) && $_GET['pay_for_order'] === 'true'
|
||||
&& ! $this->pui_helper->is_pay_for_order_ready_for_pui()
|
||||
) {
|
||||
unset( $methods[ PayUponInvoiceGateway::ID ] );
|
||||
}
|
||||
|
@ -435,31 +463,6 @@ class PayUponInvoice {
|
|||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_settings_checkout',
|
||||
function () {
|
||||
if (
|
||||
PayUponInvoiceGateway::ID === $this->current_ppcp_settings_page_id
|
||||
&& ! $this->pui_product_status->pui_is_active()
|
||||
) {
|
||||
$gateway_settings = get_option( 'woocommerce_ppcp-pay-upon-invoice-gateway_settings' );
|
||||
$gateway_enabled = $gateway_settings['enabled'] ?? '';
|
||||
if ( 'yes' === $gateway_enabled ) {
|
||||
$gateway_settings['enabled'] = 'no';
|
||||
update_option( 'woocommerce_ppcp-pay-upon-invoice-gateway_settings', $gateway_settings );
|
||||
$redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-pay-upon-invoice-gateway' );
|
||||
wp_safe_redirect( $redirect_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p></div>',
|
||||
esc_html__( 'Could not enable gateway because the connected PayPal account is not activated for Pay upon Invoice. Reconnect your account while Onboard with Pay upon Invoice is selected to try again.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_update_options_checkout_ppcp-pay-upon-invoice-gateway',
|
||||
function () {
|
||||
|
@ -504,6 +507,19 @@ class PayUponInvoice {
|
|||
</div>
|
||||
<?php
|
||||
}
|
||||
} elseif ( PayUponInvoiceGateway::ID === $this->current_ppcp_settings_page_id ) {
|
||||
$pui_gateway = WC()->payment_gateways->payment_gateways()[ PayUponInvoiceGateway::ID ];
|
||||
if ( 'yes' === $pui_gateway->get_option( 'enabled' ) ) {
|
||||
$pui_gateway->update_option( 'enabled', 'no' );
|
||||
$redirect_url = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-pay-upon-invoice-gateway' );
|
||||
wp_safe_redirect( $redirect_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p></div>',
|
||||
esc_html__( 'Could not enable gateway because the connected PayPal account is not activated for Pay upon Invoice. Reconnect your account while Onboard with Pay upon Invoice is selected to try again.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -511,9 +527,19 @@ class PayUponInvoice {
|
|||
add_action(
|
||||
'add_meta_boxes',
|
||||
function( string $post_type ) {
|
||||
if ( $post_type === 'shop_order' ) {
|
||||
/**
|
||||
* Class and function exist in WooCommerce.
|
||||
*
|
||||
* @psalm-suppress UndefinedClass
|
||||
* @psalm-suppress UndefinedFunction
|
||||
*/
|
||||
$screen = class_exists( CustomOrdersTableController::class ) && wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled()
|
||||
? wc_get_page_screen_id( 'shop-order' )
|
||||
: 'shop_order';
|
||||
|
||||
if ( $post_type === $screen ) {
|
||||
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
||||
$post_id = wc_clean( wp_unslash( $_GET['post'] ?? '' ) );
|
||||
$post_id = wc_clean( wp_unslash( $_GET['id'] ?? $_GET['post'] ?? '' ) );
|
||||
$order = wc_get_order( $post_id );
|
||||
if ( is_a( $order, WC_Order::class ) && $order->get_payment_method() === PayUponInvoiceGateway::ID ) {
|
||||
$instructions = $order->get_meta( 'ppcp_ratepay_payment_instructions_payment_reference' );
|
||||
|
@ -536,7 +562,7 @@ class PayUponInvoice {
|
|||
echo wp_kses_post( "<li>Verwendungszweck: {$payment_reference}</li>" );
|
||||
echo '</ul>';
|
||||
},
|
||||
$post_type,
|
||||
$screen,
|
||||
'side',
|
||||
'high'
|
||||
);
|
||||
|
|
|
@ -18,60 +18,6 @@ use WooCommerce\PayPalCommerce\WcGateway\Exception\GatewayGenericException;
|
|||
* Trait ProcessPaymentTrait
|
||||
*/
|
||||
trait ProcessPaymentTrait {
|
||||
/**
|
||||
* Checks if PayPal or Credit Card gateways are enabled.
|
||||
*
|
||||
* @return bool Whether any of the gateways is enabled.
|
||||
*/
|
||||
protected function gateways_enabled(): bool {
|
||||
if ( $this->config->has( 'enabled' ) && $this->config->get( 'enabled' ) ) {
|
||||
return true;
|
||||
}
|
||||
if ( $this->config->has( 'dcc_enabled' ) && $this->config->get( 'dcc_enabled' ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if vault setting is enabled.
|
||||
*
|
||||
* @return bool Whether vault settings are enabled or not.
|
||||
* @throws \WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException When a setting hasn't been found.
|
||||
*/
|
||||
protected function vault_setting_enabled(): bool {
|
||||
if ( $this->config->has( 'vault_enabled' ) && $this->config->get( 'vault_enabled' ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scheduled the vaulted payment check.
|
||||
*
|
||||
* @param int $wc_order_id The WC order ID.
|
||||
* @param int $customer_id The customer ID.
|
||||
*/
|
||||
protected function schedule_saved_payment_check( int $wc_order_id, int $customer_id ): void {
|
||||
$timestamp = 1 * MINUTE_IN_SECONDS;
|
||||
if (
|
||||
$this->config->has( 'subscription_behavior_when_vault_fails' )
|
||||
&& $this->config->get( 'subscription_behavior_when_vault_fails' ) === 'capture_auth'
|
||||
) {
|
||||
$timestamp = 0;
|
||||
}
|
||||
|
||||
as_schedule_single_action(
|
||||
time() + $timestamp,
|
||||
'woocommerce_paypal_payments_check_saved_payment',
|
||||
array(
|
||||
'order_id' => $wc_order_id,
|
||||
'customer_id' => $customer_id,
|
||||
'intent' => $this->config->has( 'intent' ) ? $this->config->get( 'intent' ) : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the payment failure.
|
||||
*
|
||||
|
@ -90,12 +36,14 @@ trait ProcessPaymentTrait {
|
|||
}
|
||||
|
||||
$this->session_handler->destroy_session_data();
|
||||
WC()->session->set( 'ppcp_subscription_id', '' );
|
||||
|
||||
wc_add_notice( $error->getMessage(), 'error' );
|
||||
|
||||
return array(
|
||||
'result' => 'failure',
|
||||
'redirect' => wc_get_checkout_url(),
|
||||
'result' => 'failure',
|
||||
'redirect' => wc_get_checkout_url(),
|
||||
'errorMessage' => $error->getMessage(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -112,6 +60,7 @@ trait ProcessPaymentTrait {
|
|||
}
|
||||
|
||||
$this->session_handler->destroy_session_data();
|
||||
WC()->session->set( 'ppcp_subscription_id', '' );
|
||||
|
||||
return array(
|
||||
'result' => 'success',
|
||||
|
|
|
@ -14,6 +14,8 @@ use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -36,6 +38,14 @@ class DCCProductStatus {
|
|||
* @var bool|null
|
||||
*/
|
||||
private $current_status_cache;
|
||||
|
||||
/**
|
||||
* If there was a request failure.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $has_request_failure = false;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
|
@ -57,6 +67,20 @@ class DCCProductStatus {
|
|||
*/
|
||||
protected $dcc_applies;
|
||||
|
||||
/**
|
||||
* The onboarding state.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $onboarding_state;
|
||||
|
||||
/**
|
||||
* The API failure registry
|
||||
*
|
||||
* @var FailureRegistry
|
||||
*/
|
||||
private $api_failure_registry;
|
||||
|
||||
/**
|
||||
* DccProductStatus constructor.
|
||||
*
|
||||
|
@ -64,17 +88,23 @@ class DCCProductStatus {
|
|||
* @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
|
||||
* @param Cache $cache The cache.
|
||||
* @param DccApplies $dcc_applies The dcc applies helper.
|
||||
* @param State $onboarding_state The onboarding state.
|
||||
* @param FailureRegistry $api_failure_registry The API failure registry.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
PartnersEndpoint $partners_endpoint,
|
||||
Cache $cache,
|
||||
DccApplies $dcc_applies
|
||||
DccApplies $dcc_applies,
|
||||
State $onboarding_state,
|
||||
FailureRegistry $api_failure_registry
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
$this->api_failure_registry = $api_failure_registry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,22 +113,34 @@ class DCCProductStatus {
|
|||
* @return bool
|
||||
*/
|
||||
public function dcc_is_active() : bool {
|
||||
if ( $this->cache->has( self::DCC_STATUS_CACHE_KEY ) ) {
|
||||
return (bool) $this->cache->get( self::DCC_STATUS_CACHE_KEY );
|
||||
if ( $this->onboarding_state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_bool( $this->current_status_cache ) ) {
|
||||
if ( $this->cache->has( self::DCC_STATUS_CACHE_KEY ) ) {
|
||||
return $this->cache->get( self::DCC_STATUS_CACHE_KEY ) === 'true';
|
||||
}
|
||||
|
||||
if ( $this->current_status_cache === true ) {
|
||||
return $this->current_status_cache;
|
||||
}
|
||||
|
||||
if ( $this->settings->has( 'products_dcc_enabled' ) && $this->settings->get( 'products_dcc_enabled' ) ) {
|
||||
if ( $this->settings->has( 'products_dcc_enabled' ) && $this->settings->get( 'products_dcc_enabled' ) === true ) {
|
||||
$this->current_status_cache = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check API failure registry to prevent multiple failed API requests.
|
||||
if ( $this->api_failure_registry->has_failure_in_timeframe( FailureRegistry::SELLER_STATUS_KEY, HOUR_IN_SECONDS ) ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return $this->current_status_cache;
|
||||
}
|
||||
|
||||
try {
|
||||
$seller_status = $this->partners_endpoint->seller_status();
|
||||
} catch ( Throwable $error ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -120,18 +162,28 @@ class DCCProductStatus {
|
|||
$this->settings->set( 'products_dcc_enabled', true );
|
||||
$this->settings->persist();
|
||||
$this->current_status_cache = true;
|
||||
$this->cache->set( self::DCC_STATUS_CACHE_KEY, true, 3 * MONTH_IN_SECONDS );
|
||||
$this->cache->set( self::DCC_STATUS_CACHE_KEY, 'true', MONTH_IN_SECONDS );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
$expiration = 3 * MONTH_IN_SECONDS;
|
||||
$expiration = MONTH_IN_SECONDS;
|
||||
if ( $this->dcc_applies->for_country_currency() ) {
|
||||
$expiration = 3 * HOUR_IN_SECONDS;
|
||||
}
|
||||
$this->cache->set( self::DCC_STATUS_CACHE_KEY, false, $expiration );
|
||||
$this->cache->set( self::DCC_STATUS_CACHE_KEY, 'false', $expiration );
|
||||
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there was a request failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_request_failure(): bool {
|
||||
return $this->has_request_failure;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
60
modules/ppcp-wc-gateway/src/Helper/DisplayManager.php
Normal file
60
modules/ppcp-wc-gateway/src/Helper/DisplayManager.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/**
|
||||
* Helper to manage the field display behaviour.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* DisplayManager class.
|
||||
*/
|
||||
class DisplayManager {
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The rules.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rules = array();
|
||||
|
||||
/**
|
||||
* FieldDisplayManager constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Settings $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a rule.
|
||||
*
|
||||
* @param string|null $key The rule key.
|
||||
* @return DisplayRule
|
||||
*/
|
||||
public function rule( string $key = null ): DisplayRule {
|
||||
if ( null === $key ) {
|
||||
$key = '_rule_' . ( (string) count( $this->rules ) );
|
||||
}
|
||||
|
||||
$rule = new DisplayRule( $key, $this->settings );
|
||||
|
||||
$this->rules[ $key ] = $rule;
|
||||
return $rule;
|
||||
}
|
||||
|
||||
}
|
262
modules/ppcp-wc-gateway/src/Helper/DisplayRule.php
Normal file
262
modules/ppcp-wc-gateway/src/Helper/DisplayRule.php
Normal file
|
@ -0,0 +1,262 @@
|
|||
<?php
|
||||
/**
|
||||
* Element used by field display manager.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
* DisplayRule class.
|
||||
*/
|
||||
class DisplayRule {
|
||||
|
||||
const CONDITION_TYPE_ELEMENT = 'element';
|
||||
const CONDITION_TYPE_BOOL = 'bool';
|
||||
|
||||
const CONDITION_OPERATION_EQUALS = 'equals';
|
||||
const CONDITION_OPERATION_NOT_EQUALS = 'not_equals';
|
||||
const CONDITION_OPERATION_IN = 'in';
|
||||
const CONDITION_OPERATION_NOT_IN = 'not_in';
|
||||
const CONDITION_OPERATION_EMPTY = 'empty';
|
||||
const CONDITION_OPERATION_NOT_EMPTY = 'not_empty';
|
||||
|
||||
const ACTION_TYPE_ELEMENT = 'element';
|
||||
|
||||
const ACTION_VISIBLE = 'visible';
|
||||
const ACTION_ENABLE = 'enable';
|
||||
|
||||
/**
|
||||
* The element selector.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $key;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* The conditions of this rule.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* The actions of this rule.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $actions = array();
|
||||
|
||||
/**
|
||||
* Indicates if this class should add selector prefixes.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $add_selector_prefixes = true;
|
||||
|
||||
/**
|
||||
* FieldDisplayElement constructor.
|
||||
*
|
||||
* @param string $key The rule key.
|
||||
* @param Settings $settings The settings.
|
||||
*/
|
||||
public function __construct( string $key, Settings $settings ) {
|
||||
$this->key = $key;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition related to an HTML element.
|
||||
*
|
||||
* @param string $selector The condition selector.
|
||||
* @param mixed $value The value to compare against.
|
||||
* @param string $operation The condition operation (ex: equals, differs, in, not_empty, empty).
|
||||
* @return self
|
||||
*/
|
||||
public function condition_element( string $selector, $value, string $operation = self::CONDITION_OPERATION_EQUALS ): self {
|
||||
$this->add_condition(
|
||||
array(
|
||||
'type' => self::CONDITION_TYPE_ELEMENT,
|
||||
'selector' => $selector,
|
||||
'operation' => $operation,
|
||||
'value' => $value,
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition related to a bool check.
|
||||
*
|
||||
* @param bool $value The value to enable / disable the condition.
|
||||
* @return self
|
||||
*/
|
||||
public function condition_is_true( bool $value ): self {
|
||||
$this->add_condition(
|
||||
array(
|
||||
'type' => self::CONDITION_TYPE_BOOL,
|
||||
'value' => $value,
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition related to the settings.
|
||||
*
|
||||
* @param string $settings_key The settings key.
|
||||
* @param mixed $value The value to compare against.
|
||||
* @param string $operation The condition operation (ex: equals, differs, in, not_empty, empty).
|
||||
* @return self
|
||||
*/
|
||||
public function condition_is_settings( string $settings_key, $value, string $operation = self::CONDITION_OPERATION_EQUALS ): self {
|
||||
$settings_value = null;
|
||||
|
||||
if ( $this->settings->has( $settings_key ) ) {
|
||||
$settings_value = $this->settings->get( $settings_key );
|
||||
}
|
||||
|
||||
$this->condition_is_true( $this->resolve_operation( $settings_value, $value, $operation ) );
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition to show/hide the element.
|
||||
*
|
||||
* @param string $selector The condition selector.
|
||||
*/
|
||||
public function action_visible( string $selector ): self {
|
||||
$this->add_action(
|
||||
array(
|
||||
'type' => self::ACTION_TYPE_ELEMENT,
|
||||
'selector' => $selector,
|
||||
'action' => self::ACTION_VISIBLE,
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition to enable/disable the element.
|
||||
*
|
||||
* @param string $selector The condition selector.
|
||||
*/
|
||||
public function action_enable( string $selector ): self {
|
||||
$this->add_action(
|
||||
array(
|
||||
'type' => self::ACTION_TYPE_ELEMENT,
|
||||
'selector' => $selector,
|
||||
'action' => self::ACTION_ENABLE,
|
||||
)
|
||||
);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition to the rule.
|
||||
*
|
||||
* @param array $options The condition options.
|
||||
* @return void
|
||||
*/
|
||||
private function add_condition( array $options ): void {
|
||||
if ( $this->add_selector_prefixes && isset( $options['selector'] ) ) {
|
||||
$options['selector'] = '#ppcp-' . $options['selector']; // Refers to the input.
|
||||
}
|
||||
|
||||
if ( ! isset( $options['key'] ) ) {
|
||||
$options['key'] = '_condition_' . ( (string) count( $this->conditions ) );
|
||||
}
|
||||
|
||||
$this->conditions[] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an action to do.
|
||||
*
|
||||
* @param array $options The action options.
|
||||
* @return void
|
||||
*/
|
||||
private function add_action( array $options ): void {
|
||||
if ( $this->add_selector_prefixes && isset( $options['selector'] ) ) {
|
||||
$options['selector'] = '#field-' . $options['selector']; // Refers to the whole field.
|
||||
}
|
||||
|
||||
if ( ! isset( $options['key'] ) ) {
|
||||
$options['key'] = '_action_' . ( (string) count( $this->actions ) );
|
||||
}
|
||||
|
||||
$this->actions[] = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if selector prefixes like, "#ppcp-" or "#field-" should be added to condition or action selectors.
|
||||
*
|
||||
* @param bool $add_selector_prefixes If should add prefixes.
|
||||
* @return self
|
||||
*/
|
||||
public function should_add_selector_prefixes( bool $add_selector_prefixes = true ): self {
|
||||
$this->add_selector_prefixes = $add_selector_prefixes;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a condition related to the settings.
|
||||
*
|
||||
* @param mixed $value_1 The value 1.
|
||||
* @param mixed $value_2 The value 2.
|
||||
* @param string $operation The condition operation (ex: equals, differs, in, not_empty, empty).
|
||||
* @return bool
|
||||
*/
|
||||
private function resolve_operation( $value_1, $value_2, string $operation ): bool {
|
||||
switch ( $operation ) {
|
||||
case self::CONDITION_OPERATION_EQUALS:
|
||||
return $value_1 === $value_2;
|
||||
case self::CONDITION_OPERATION_NOT_EQUALS:
|
||||
return $value_1 !== $value_2;
|
||||
case self::CONDITION_OPERATION_IN:
|
||||
return in_array( $value_1, $value_2, true );
|
||||
case self::CONDITION_OPERATION_NOT_IN:
|
||||
return ! in_array( $value_1, $value_2, true );
|
||||
case self::CONDITION_OPERATION_EMPTY:
|
||||
return empty( $value_1 );
|
||||
case self::CONDITION_OPERATION_NOT_EMPTY:
|
||||
return ! empty( $value_1 );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array representation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function to_array(): array {
|
||||
return array(
|
||||
'key' => $this->key,
|
||||
'conditions' => $this->conditions,
|
||||
'actions' => $this->actions,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns JSON representation.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function json(): string {
|
||||
return wp_json_encode( $this->to_array() ) ?: '';
|
||||
}
|
||||
|
||||
}
|
|
@ -13,6 +13,8 @@ use Throwable;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PartnersEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\SellerStatusProduct;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\FailureRegistry;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -35,6 +37,14 @@ class PayUponInvoiceProductStatus {
|
|||
* @var bool|null
|
||||
*/
|
||||
private $current_status_cache;
|
||||
|
||||
/**
|
||||
* If there was a request failure.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $has_request_failure = false;
|
||||
|
||||
/**
|
||||
* The settings.
|
||||
*
|
||||
|
@ -49,21 +59,41 @@ class PayUponInvoiceProductStatus {
|
|||
*/
|
||||
private $partners_endpoint;
|
||||
|
||||
/**
|
||||
* The onboarding status
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $onboarding_state;
|
||||
|
||||
/**
|
||||
* The API failure registry
|
||||
*
|
||||
* @var FailureRegistry
|
||||
*/
|
||||
private $api_failure_registry;
|
||||
|
||||
/**
|
||||
* PayUponInvoiceProductStatus constructor.
|
||||
*
|
||||
* @param Settings $settings The Settings.
|
||||
* @param PartnersEndpoint $partners_endpoint The Partner Endpoint.
|
||||
* @param Cache $cache The cache.
|
||||
* @param State $onboarding_state The onboarding state.
|
||||
* @param FailureRegistry $api_failure_registry The API failure registry.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
PartnersEndpoint $partners_endpoint,
|
||||
Cache $cache
|
||||
Cache $cache,
|
||||
State $onboarding_state,
|
||||
FailureRegistry $api_failure_registry
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->settings = $settings;
|
||||
$this->partners_endpoint = $partners_endpoint;
|
||||
$this->cache = $cache;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
$this->api_failure_registry = $api_failure_registry;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,21 +102,33 @@ class PayUponInvoiceProductStatus {
|
|||
* @return bool
|
||||
*/
|
||||
public function pui_is_active() : bool {
|
||||
if ( $this->cache->has( self::PUI_STATUS_CACHE_KEY ) ) {
|
||||
return (bool) $this->cache->get( self::PUI_STATUS_CACHE_KEY );
|
||||
if ( $this->onboarding_state->current_state() < State::STATE_ONBOARDED ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_bool( $this->current_status_cache ) ) {
|
||||
if ( $this->cache->has( self::PUI_STATUS_CACHE_KEY ) ) {
|
||||
return $this->cache->get( self::PUI_STATUS_CACHE_KEY ) === 'true';
|
||||
}
|
||||
|
||||
if ( $this->current_status_cache === true ) {
|
||||
return $this->current_status_cache;
|
||||
}
|
||||
if ( $this->settings->has( 'products_pui_enabled' ) && $this->settings->get( 'products_pui_enabled' ) ) {
|
||||
if ( $this->settings->has( 'products_pui_enabled' ) && $this->settings->get( 'products_pui_enabled' ) === true ) {
|
||||
$this->current_status_cache = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check API failure registry to prevent multiple failed API requests.
|
||||
if ( $this->api_failure_registry->has_failure_in_timeframe( FailureRegistry::SELLER_STATUS_KEY, HOUR_IN_SECONDS ) ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return $this->current_status_cache;
|
||||
}
|
||||
|
||||
try {
|
||||
$seller_status = $this->partners_endpoint->seller_status();
|
||||
} catch ( Throwable $error ) {
|
||||
$this->has_request_failure = true;
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
}
|
||||
|
@ -112,13 +154,23 @@ class PayUponInvoiceProductStatus {
|
|||
$this->settings->set( 'products_pui_enabled', true );
|
||||
$this->settings->persist();
|
||||
$this->current_status_cache = true;
|
||||
$this->cache->set( self::PUI_STATUS_CACHE_KEY, true, 3 * MONTH_IN_SECONDS );
|
||||
$this->cache->set( self::PUI_STATUS_CACHE_KEY, 'true', MONTH_IN_SECONDS );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->cache->set( self::PUI_STATUS_CACHE_KEY, false, 3 * MONTH_IN_SECONDS );
|
||||
$this->cache->set( self::PUI_STATUS_CACHE_KEY, 'false', MONTH_IN_SECONDS );
|
||||
|
||||
$this->current_status_cache = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there was a request failure.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_request_failure(): bool {
|
||||
return $this->has_request_failure;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
195
modules/ppcp-wc-gateway/src/Helper/RefundFeesUpdater.php
Normal file
195
modules/ppcp-wc-gateway/src/Helper/RefundFeesUpdater.php
Normal file
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
/**
|
||||
* The RefundFeesUpdater helper.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WP_Comment;
|
||||
|
||||
/**
|
||||
* CheckoutHelper class.
|
||||
*/
|
||||
class RefundFeesUpdater {
|
||||
|
||||
/**
|
||||
* The Order Endpoint.
|
||||
*
|
||||
* @var OrderEndpoint
|
||||
*/
|
||||
private $order_endpoint;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* RefundFeesUpdater constructor.
|
||||
*
|
||||
* @param OrderEndpoint $order_endpoint The Order Endpoint.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct( OrderEndpoint $order_endpoint, LoggerInterface $logger ) {
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the fees meta for a given order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return void
|
||||
*/
|
||||
public function update( WC_Order $wc_order ): void {
|
||||
$paypal_order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
|
||||
if ( ! $paypal_order_id ) {
|
||||
$this->logger->error(
|
||||
sprintf( 'Failed to update order paypal refund fees. No PayPal order_id. [wc_order: %s]', $wc_order->get_id() )
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf( 'Updating order paypal refund fees. [wc_order: %s, paypal_order: %s]', $wc_order->get_id(), $paypal_order_id )
|
||||
);
|
||||
|
||||
$paypal_order = $this->order_endpoint->order( $paypal_order_id );
|
||||
$purchase_units = $paypal_order->purchase_units();
|
||||
|
||||
$gross_amount_total = 0.0;
|
||||
$fee_total = 0.0;
|
||||
$net_amount_total = 0.0;
|
||||
$currency_codes = array();
|
||||
$refunds_ids = array();
|
||||
|
||||
foreach ( $purchase_units as $purchase_unit ) {
|
||||
$payments = $purchase_unit->payments();
|
||||
|
||||
if ( ! $payments ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$refunds = $payments->refunds();
|
||||
|
||||
foreach ( $refunds as $refund ) {
|
||||
$breakdown = $refund->seller_payable_breakdown();
|
||||
$refunds_ids[] = $refund->id();
|
||||
|
||||
if ( ! $breakdown ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$gross_amount = $breakdown->gross_amount();
|
||||
if ( $gross_amount ) {
|
||||
$gross_amount_total += $gross_amount->value();
|
||||
$currency_codes[] = $gross_amount->currency_code();
|
||||
}
|
||||
|
||||
$paypal_fee = $breakdown->paypal_fee();
|
||||
if ( $paypal_fee ) {
|
||||
$fee_total += $paypal_fee->value();
|
||||
$currency_codes[] = $paypal_fee->currency_code();
|
||||
}
|
||||
|
||||
$net_amount = $breakdown->net_amount();
|
||||
if ( $net_amount ) {
|
||||
$net_amount_total += $net_amount->value();
|
||||
$currency_codes[] = $net_amount->currency_code();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$currency_codes = array_unique( $currency_codes );
|
||||
|
||||
if ( count( $currency_codes ) > 1 ) {
|
||||
// There are multiple different currencies codes in the refunds.
|
||||
|
||||
$this->logger->warning(
|
||||
sprintf(
|
||||
'Updating order paypal refund fees. Multiple currencies detected. [wc_order: %s, paypal_order: %s, currencies: %s]',
|
||||
$wc_order->get_id(),
|
||||
$paypal_order_id,
|
||||
implode( ',', $currency_codes )
|
||||
)
|
||||
);
|
||||
|
||||
$wc_order->update_meta_data( PayPalGateway::REFUND_FEES_META_KEY, array() );
|
||||
return;
|
||||
}
|
||||
|
||||
$currency_code = current( $currency_codes ) ?: '';
|
||||
|
||||
$meta_data = array(
|
||||
'gross_amount' => ( new Money( $gross_amount_total, $currency_code ) )->to_array(),
|
||||
'paypal_fee' => ( new Money( $fee_total, $currency_code ) )->to_array(),
|
||||
'net_amount' => ( new Money( $net_amount_total, $currency_code ) )->to_array(),
|
||||
);
|
||||
|
||||
$wc_order->update_meta_data( PayPalGateway::REFUND_FEES_META_KEY, $meta_data );
|
||||
$wc_order->save();
|
||||
|
||||
$order_notes = $this->get_order_notes( $wc_order );
|
||||
|
||||
foreach ( $refunds_ids as $refund_id ) {
|
||||
$has_note = false;
|
||||
foreach ( $order_notes as $order_note ) {
|
||||
if ( strpos( $order_note->comment_content, $refund_id ) !== false ) {
|
||||
$has_note = true;
|
||||
}
|
||||
}
|
||||
if ( ! $has_note ) {
|
||||
$wc_order->add_order_note( sprintf( 'PayPal refund ID: %s', $refund_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf( 'Updated order paypal refund fees. [wc_order: %s, paypal_order: %s]', $wc_order->get_id(), $paypal_order_id )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all order notes
|
||||
* Based on WC_Order::get_customer_order_notes
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return WP_Comment[]
|
||||
*/
|
||||
private function get_order_notes( WC_Order $wc_order ): array {
|
||||
$notes = array();
|
||||
$args = array(
|
||||
'post_id' => $wc_order->get_id(),
|
||||
);
|
||||
|
||||
// By default, WooCommerce excludes comments of the comment_type order_note.
|
||||
// We need to remove this filter to get the order notes.
|
||||
remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) );
|
||||
|
||||
$comments = get_comments( $args );
|
||||
|
||||
if ( is_array( $comments ) ) {
|
||||
foreach ( $comments as $comment ) {
|
||||
if ( $comment instanceof WP_Comment ) {
|
||||
$notes[] = $comment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) );
|
||||
|
||||
return $notes;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,7 +9,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Helper;
|
||||
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +36,6 @@ class SettingsStatus {
|
|||
* Check whether Pay Later message is enabled either for checkout, cart or product page.
|
||||
*
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_messaging_enabled(): bool {
|
||||
$messaging_enabled = $this->settings->has( 'pay_later_messaging_enabled' ) && $this->settings->get( 'pay_later_messaging_enabled' );
|
||||
|
@ -51,27 +49,15 @@ class SettingsStatus {
|
|||
*
|
||||
* @param string $location The location setting name.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_messaging_enabled_for_location( string $location ): bool {
|
||||
if ( ! $this->is_pay_later_messaging_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_messaging_locations' ) ? $this->settings->get( 'pay_later_messaging_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $location, $selected_locations, true );
|
||||
return $this->is_pay_later_messaging_enabled() && $this->is_enabled_for_location( 'pay_later_messaging_locations', $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Pay Later button is enabled either for checkout, cart or product page.
|
||||
*
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled(): bool {
|
||||
$pay_later_button_enabled = $this->settings->has( 'pay_later_button_enabled' ) && $this->settings->get( 'pay_later_button_enabled' );
|
||||
|
@ -85,45 +71,11 @@ class SettingsStatus {
|
|||
*
|
||||
* @param string $location The location.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled_for_location( string $location ): bool {
|
||||
if ( ! $this->is_pay_later_button_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_button_locations' ) ? $this->settings->get( 'pay_later_button_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array( $location, $selected_locations, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether Pay Later button is enabled for a given context.
|
||||
*
|
||||
* @param string $context The context.
|
||||
* @return bool true if is enabled, otherwise false.
|
||||
* @throws NotFoundException When a setting was not found.
|
||||
*/
|
||||
public function is_pay_later_button_enabled_for_context( string $context ): bool {
|
||||
if ( ! $this->is_pay_later_button_enabled() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$selected_locations = $this->settings->has( 'pay_later_button_locations' ) ? $this->settings->get( 'pay_later_button_locations' ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$enabled_for_current_location = $this->is_pay_later_button_enabled_for_location( $context );
|
||||
$enabled_for_product = $this->is_pay_later_button_enabled_for_location( 'product' );
|
||||
$enabled_for_mini_cart = $this->is_pay_later_button_enabled_for_location( 'mini-cart' );
|
||||
|
||||
return $context === 'product' ? $enabled_for_product || $enabled_for_mini_cart : $enabled_for_current_location;
|
||||
return $this->is_pay_later_button_enabled() &&
|
||||
( $this->is_enabled_for_location( 'pay_later_button_locations', $location ) ||
|
||||
( 'product' === $location && $this->is_enabled_for_location( 'pay_later_button_locations', 'mini-cart' ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +85,36 @@ class SettingsStatus {
|
|||
* @return bool true if is enabled, otherwise false.
|
||||
*/
|
||||
public function is_smart_button_enabled_for_location( string $location ): bool {
|
||||
$selected_locations = $this->settings->has( 'smart_button_locations' ) ? $this->settings->get( 'smart_button_locations' ) : array();
|
||||
return $this->is_enabled_for_location( 'smart_button_locations', $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapts the context value to match the location settings.
|
||||
*
|
||||
* @param string $location The location/context.
|
||||
* @return string
|
||||
*/
|
||||
protected function normalize_location( string $location ): string {
|
||||
if ( 'pay-now' === $location ) {
|
||||
$location = 'checkout';
|
||||
}
|
||||
if ( 'checkout-block' === $location ) {
|
||||
$location = 'checkout-block-express';
|
||||
}
|
||||
return $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the locations field in the settings includes the given location.
|
||||
*
|
||||
* @param string $setting_name The name of the enabled locations field in the settings.
|
||||
* @param string $location The location.
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_enabled_for_location( string $setting_name, string $location ): bool {
|
||||
$location = $this->normalize_location( $location );
|
||||
|
||||
$selected_locations = $this->settings->has( $setting_name ) ? $this->settings->get( $setting_name ) : array();
|
||||
|
||||
if ( empty( $selected_locations ) ) {
|
||||
return false;
|
||||
|
|
|
@ -13,11 +13,16 @@ use WC_Payment_Gateway;
|
|||
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||
|
||||
/**
|
||||
* Creates the admin message about the gateway being enabled without the PayPal gateway.
|
||||
*/
|
||||
class GatewayWithoutPayPalAdminNotice {
|
||||
private const NOTICE_OK = '';
|
||||
private const NOTICE_DISABLED_GATEWAY = 'disabled_gateway';
|
||||
private const NOTICE_DISABLED_LOCATION = 'disabled_location';
|
||||
|
||||
/**
|
||||
* The gateway ID.
|
||||
*
|
||||
|
@ -53,27 +58,37 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
*/
|
||||
private $is_ppcp_settings_page;
|
||||
|
||||
/**
|
||||
* The Settings status helper.
|
||||
*
|
||||
* @var SettingsStatus|null
|
||||
*/
|
||||
protected $settings_status;
|
||||
|
||||
/**
|
||||
* ConnectAdminNotice constructor.
|
||||
*
|
||||
* @param string $id The gateway ID.
|
||||
* @param State $state The state.
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param bool $is_payments_page Whether the current page is the WC payment page.
|
||||
* @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page.
|
||||
* @param string $id The gateway ID.
|
||||
* @param State $state The state.
|
||||
* @param ContainerInterface $settings The settings.
|
||||
* @param bool $is_payments_page Whether the current page is the WC payment page.
|
||||
* @param bool $is_ppcp_settings_page Whether the current page is the PPCP settings page.
|
||||
* @param SettingsStatus|null $settings_status The Settings status helper.
|
||||
*/
|
||||
public function __construct(
|
||||
string $id,
|
||||
State $state,
|
||||
ContainerInterface $settings,
|
||||
bool $is_payments_page,
|
||||
bool $is_ppcp_settings_page
|
||||
bool $is_ppcp_settings_page,
|
||||
?SettingsStatus $settings_status = null
|
||||
) {
|
||||
$this->id = $id;
|
||||
$this->state = $state;
|
||||
$this->settings = $settings;
|
||||
$this->is_payments_page = $is_payments_page;
|
||||
$this->is_ppcp_settings_page = $is_ppcp_settings_page;
|
||||
$this->settings_status = $settings_status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,8 +97,25 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
* @return Message|null
|
||||
*/
|
||||
public function message(): ?Message {
|
||||
if ( ! $this->should_display() ) {
|
||||
return null;
|
||||
$notice_type = $this->check();
|
||||
|
||||
switch ( $notice_type ) {
|
||||
case self::NOTICE_DISABLED_GATEWAY:
|
||||
/* translators: %1$s the gateway name, %2$s URL. */
|
||||
$text = __(
|
||||
'%1$s cannot be used without the PayPal gateway. <a href="%2$s">Enable the PayPal gateway</a>.',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
break;
|
||||
case self::NOTICE_DISABLED_LOCATION:
|
||||
/* translators: %1$s the gateway name, %2$s URL. */
|
||||
$text = __(
|
||||
'%1$s cannot be used without enabling the Checkout location for the PayPal gateway. <a href="%2$s">Enable the Checkout location</a>.',
|
||||
'woocommerce-paypal-payments'
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
$gateway = $this->get_gateway();
|
||||
|
@ -94,11 +126,7 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
$name = $gateway->get_method_title();
|
||||
|
||||
$message = sprintf(
|
||||
/* translators: %1$s the gateway name, %2$s URL. */
|
||||
__(
|
||||
'%1$s cannot be used without the PayPal gateway. <a href="%2$s">Enable the PayPal gateway</a>.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
$text,
|
||||
$name,
|
||||
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
|
||||
);
|
||||
|
@ -106,22 +134,33 @@ class GatewayWithoutPayPalAdminNotice {
|
|||
}
|
||||
|
||||
/**
|
||||
* Whether the message should be displayed.
|
||||
* Checks whether one of the messages should be displayed.
|
||||
*
|
||||
* @return bool
|
||||
* @return string One of the NOTICE_* constants.
|
||||
*/
|
||||
protected function should_display(): bool {
|
||||
protected function check(): string {
|
||||
if ( State::STATE_ONBOARDED !== $this->state->current_state() ||
|
||||
( ! $this->is_payments_page && ! $this->is_ppcp_settings_page ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' ) ) {
|
||||
return false;
|
||||
return self::NOTICE_OK;
|
||||
}
|
||||
|
||||
$gateway = $this->get_gateway();
|
||||
$gateway = $this->get_gateway();
|
||||
$gateway_enabled = $gateway && wc_string_to_bool( $gateway->get_option( 'enabled' ) );
|
||||
|
||||
return $gateway && wc_string_to_bool( $gateway->get_option( 'enabled' ) );
|
||||
if ( ! $gateway_enabled ) {
|
||||
return self::NOTICE_OK;
|
||||
}
|
||||
|
||||
$paypal_enabled = $this->settings->has( 'enabled' ) && $this->settings->get( 'enabled' );
|
||||
if ( ! $paypal_enabled ) {
|
||||
return self::NOTICE_DISABLED_GATEWAY;
|
||||
}
|
||||
|
||||
if ( $this->settings_status && ! $this->settings_status->is_smart_button_enabled_for_location( 'checkout' ) ) {
|
||||
return self::NOTICE_DISABLED_LOCATION;
|
||||
}
|
||||
|
||||
return self::NOTICE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
/**
|
||||
* Registers the admin message about unsupported currency set in WC shop settings.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\WcGateway\Notice
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Notice;
|
||||
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class UnsupportedCurrencyAdminNotice
|
||||
*/
|
||||
class UnsupportedCurrencyAdminNotice {
|
||||
|
||||
/**
|
||||
* The state.
|
||||
*
|
||||
* @var State
|
||||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* The supported currencies.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $supported_currencies;
|
||||
|
||||
/**
|
||||
* The shop currency.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $shop_currency;
|
||||
|
||||
/**
|
||||
* Indicates if we're on the WooCommerce gateways list page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_wc_gateways_list_page;
|
||||
|
||||
/**
|
||||
* Indicates if we're on a PPCP Settings page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_ppcp_settings_page;
|
||||
|
||||
/**
|
||||
* UnsupportedCurrencyAdminNotice constructor.
|
||||
*
|
||||
* @param State $state The state.
|
||||
* @param string $shop_currency The shop currency.
|
||||
* @param array $supported_currencies The supported currencies.
|
||||
* @param bool $is_wc_gateways_list_page Indicates if we're on the WooCommerce gateways list page.
|
||||
* @param bool $is_ppcp_settings_page Indicates if we're on a PPCP Settings page.
|
||||
*/
|
||||
public function __construct(
|
||||
State $state,
|
||||
string $shop_currency,
|
||||
array $supported_currencies,
|
||||
bool $is_wc_gateways_list_page,
|
||||
bool $is_ppcp_settings_page
|
||||
) {
|
||||
$this->state = $state;
|
||||
$this->shop_currency = $shop_currency;
|
||||
$this->supported_currencies = $supported_currencies;
|
||||
$this->is_wc_gateways_list_page = $is_wc_gateways_list_page;
|
||||
$this->is_ppcp_settings_page = $is_ppcp_settings_page;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message.
|
||||
*
|
||||
* @return Message|null
|
||||
*/
|
||||
public function unsupported_currency_message() {
|
||||
if ( ! $this->should_display() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$paypal_currency_support_url = 'https://developer.paypal.com/api/rest/reference/currency-codes/';
|
||||
|
||||
$message = sprintf(
|
||||
/* translators: %1$s the shop currency, %2$s the PayPal currency support page link opening HTML tag, %3$s the link ending HTML tag. */
|
||||
__(
|
||||
'Attention: Your current WooCommerce store currency (%1$s) is not supported by PayPal. Please update your store currency to one that is supported by PayPal to ensure smooth transactions. Visit the %2$sPayPal currency support page%3$s for more information on supported currencies.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
$this->shop_currency,
|
||||
'<a href="' . esc_url( $paypal_currency_support_url ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
return new Message( $message, 'warning', true, 'ppcp-notice-wrapper' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the message should display.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function should_display(): bool {
|
||||
return $this->state->current_state() === State::STATE_ONBOARDED
|
||||
&& ! $this->currency_supported()
|
||||
&& ( $this->is_wc_gateways_list_page || $this->is_ppcp_settings_page );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the currency is supported by PayPal.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function currency_supported(): bool {
|
||||
$currency = $this->shop_currency;
|
||||
$supported_currencies = $this->supported_currencies;
|
||||
return in_array( $currency, $supported_currencies, true );
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
|||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
|
@ -22,14 +23,16 @@ trait OrderMetaTrait {
|
|||
/**
|
||||
* Adds common metadata to the order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WC order to which metadata will be added.
|
||||
* @param Order $order The PayPal order.
|
||||
* @param Environment $environment The environment.
|
||||
* @param WC_Order $wc_order The WC order to which metadata will be added.
|
||||
* @param Order $order The PayPal order.
|
||||
* @param Environment $environment The environment.
|
||||
* @param OrderTransient|null $order_transient The order transient helper.
|
||||
*/
|
||||
protected function add_paypal_meta(
|
||||
WC_Order $wc_order,
|
||||
Order $order,
|
||||
Environment $environment
|
||||
Environment $environment,
|
||||
OrderTransient $order_transient = null
|
||||
): void {
|
||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||
|
@ -43,6 +46,8 @@ trait OrderMetaTrait {
|
|||
}
|
||||
|
||||
$wc_order->save();
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,9 +10,11 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderHelper;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\ThreeDSecure;
|
||||
|
@ -114,6 +116,13 @@ class OrderProcessor {
|
|||
*/
|
||||
private $order_helper;
|
||||
|
||||
/**
|
||||
* Array to store temporary order data changes to restore after processing.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $restore_order_data = array();
|
||||
|
||||
/**
|
||||
* OrderProcessor constructor.
|
||||
*
|
||||
|
@ -161,11 +170,31 @@ class OrderProcessor {
|
|||
* @return bool
|
||||
*/
|
||||
public function process( \WC_Order $wc_order ): bool {
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
$order = $this->session_handler->order() ?? $this->order_endpoint->order( $order_id );
|
||||
// phpcs:ignore WordPress.Security.NonceVerification
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY ) ?: wc_clean( wp_unslash( $_POST['paypal_order_id'] ?? '' ) );
|
||||
$order = $this->session_handler->order();
|
||||
if ( ! $order && is_string( $order_id ) && $order_id ) {
|
||||
$order = $this->order_endpoint->order( $order_id );
|
||||
}
|
||||
if ( ! $order ) {
|
||||
$this->last_error = __( 'No PayPal order found in the current WooCommerce session.', 'woocommerce-paypal-payments' );
|
||||
return false;
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
if ( ! $order_id ) {
|
||||
$this->logger->warning(
|
||||
sprintf(
|
||||
'No PayPal order ID found in order #%d meta.',
|
||||
$wc_order->get_id()
|
||||
)
|
||||
);
|
||||
$this->last_error = __( 'Could not retrieve order. Maybe it was already completed or this browser is not supported. Please check your email or try again with a different browser.', 'woocommerce-paypal-payments' );
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$order = $this->order_endpoint->order( $order_id );
|
||||
} catch ( RuntimeException $exception ) {
|
||||
$this->last_error = __( 'Could not retrieve PayPal order.', 'woocommerce-paypal-payments' );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->add_paypal_meta( $wc_order, $order, $this->environment );
|
||||
|
@ -270,8 +299,12 @@ class OrderProcessor {
|
|||
* @return Order
|
||||
*/
|
||||
public function patch_order( \WC_Order $wc_order, Order $order ): Order {
|
||||
$this->apply_outbound_order_filters( $wc_order );
|
||||
$updated_order = $this->order_factory->from_wc_order( $wc_order, $order );
|
||||
$order = $this->order_endpoint->patch_order_with( $order, $updated_order );
|
||||
$this->restore_order_from_filters( $wc_order );
|
||||
|
||||
$order = $this->order_endpoint->patch_order_with( $order, $updated_order );
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
@ -301,4 +334,48 @@ class OrderProcessor {
|
|||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies filters to the WC_Order, so they are reflected only on PayPal Order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WoocOmmerce Order.
|
||||
* @return void
|
||||
*/
|
||||
private function apply_outbound_order_filters( WC_Order $wc_order ): void {
|
||||
$items = $wc_order->get_items();
|
||||
|
||||
$this->restore_order_data['names'] = array();
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
if ( ! $item instanceof \WC_Order_Item ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$original_name = $item->get_name();
|
||||
$new_name = apply_filters( 'woocommerce_paypal_payments_order_line_item_name', $original_name, $item->get_id(), $wc_order->get_id() );
|
||||
|
||||
if ( $new_name !== $original_name ) {
|
||||
$this->restore_order_data['names'][ $item->get_id() ] = $original_name;
|
||||
$item->set_name( $new_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores the WC_Order to it's state before filters.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce Order.
|
||||
* @return void
|
||||
*/
|
||||
private function restore_order_from_filters( WC_Order $wc_order ): void {
|
||||
if ( is_array( $this->restore_order_data['names'] ?? null ) ) {
|
||||
foreach ( $this->restore_order_data['names'] as $wc_item_id => $original_name ) {
|
||||
$wc_item = $wc_order->get_item( $wc_item_id, false );
|
||||
|
||||
if ( $wc_item ) {
|
||||
$wc_item->set_name( $original_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,16 +11,19 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
|||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\PaymentsEndpoint;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Amount;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Authorization;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\AuthorizationStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Money;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payments;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Refund;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\RefundCapture;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\RefundFeesUpdater;
|
||||
|
||||
/**
|
||||
* Class RefundProcessor
|
||||
|
@ -53,24 +56,33 @@ class RefundProcessor {
|
|||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* The refund fees updater.
|
||||
*
|
||||
* @var RefundFeesUpdater
|
||||
*/
|
||||
private $refund_fees_updater;
|
||||
|
||||
/**
|
||||
* RefundProcessor constructor.
|
||||
*
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
* @param OrderEndpoint $order_endpoint The order endpoint.
|
||||
* @param PaymentsEndpoint $payments_endpoint The payments endpoint.
|
||||
* @param RefundFeesUpdater $refund_fees_updater The refund fees updater.
|
||||
* @param LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct( OrderEndpoint $order_endpoint, PaymentsEndpoint $payments_endpoint, LoggerInterface $logger ) {
|
||||
public function __construct( OrderEndpoint $order_endpoint, PaymentsEndpoint $payments_endpoint, RefundFeesUpdater $refund_fees_updater, LoggerInterface $logger ) {
|
||||
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
$this->logger = $logger;
|
||||
$this->order_endpoint = $order_endpoint;
|
||||
$this->payments_endpoint = $payments_endpoint;
|
||||
$this->refund_fees_updater = $refund_fees_updater;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a refund.
|
||||
*
|
||||
* @param \WC_Order $wc_order The WooCommerce order.
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @param float|null $amount The refund amount.
|
||||
* @param string $reason The reason for the refund.
|
||||
*
|
||||
|
@ -78,7 +90,7 @@ class RefundProcessor {
|
|||
*
|
||||
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.Missing
|
||||
*/
|
||||
public function process( \WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
|
||||
public function process( WC_Order $wc_order, float $amount = null, string $reason = '' ) : bool {
|
||||
try {
|
||||
$order_id = $wc_order->get_meta( PayPalGateway::ORDER_ID_META_KEY );
|
||||
if ( ! $order_id ) {
|
||||
|
@ -87,15 +99,7 @@ class RefundProcessor {
|
|||
|
||||
$order = $this->order_endpoint->order( $order_id );
|
||||
|
||||
$purchase_units = $order->purchase_units();
|
||||
if ( ! $purchase_units ) {
|
||||
throw new RuntimeException( 'No purchase units.' );
|
||||
}
|
||||
|
||||
$payments = $purchase_units[0]->payments();
|
||||
if ( ! $payments ) {
|
||||
throw new RuntimeException( 'No payments.' );
|
||||
}
|
||||
$payments = $this->get_payments( $order );
|
||||
|
||||
$this->logger->debug(
|
||||
sprintf(
|
||||
|
@ -109,39 +113,14 @@ class RefundProcessor {
|
|||
|
||||
switch ( $mode ) {
|
||||
case self::REFUND_MODE_REFUND:
|
||||
$captures = $payments->captures();
|
||||
if ( ! $captures ) {
|
||||
throw new RuntimeException( 'No capture.' );
|
||||
}
|
||||
|
||||
$capture = $captures[0];
|
||||
$refund = new Refund(
|
||||
$capture,
|
||||
$capture->invoice_id(),
|
||||
$reason,
|
||||
new Amount(
|
||||
new Money( $amount, $wc_order->get_currency() )
|
||||
)
|
||||
);
|
||||
$refund_id = $this->payments_endpoint->refund( $refund );
|
||||
$refund_id = $this->refund( $order, $wc_order, $amount, $reason );
|
||||
|
||||
$this->add_refund_to_meta( $wc_order, $refund_id );
|
||||
$this->refund_fees_updater->update( $wc_order );
|
||||
|
||||
break;
|
||||
case self::REFUND_MODE_VOID:
|
||||
$voidable_authorizations = array_filter(
|
||||
$payments->authorizations(),
|
||||
function ( Authorization $authorization ): bool {
|
||||
return $authorization->is_voidable();
|
||||
}
|
||||
);
|
||||
if ( ! $voidable_authorizations ) {
|
||||
throw new RuntimeException( 'No voidable authorizations.' );
|
||||
}
|
||||
|
||||
foreach ( $voidable_authorizations as $authorization ) {
|
||||
$this->payments_endpoint->void( $authorization );
|
||||
}
|
||||
$this->void( $order );
|
||||
|
||||
$wc_order->set_status( 'refunded' );
|
||||
$wc_order->save();
|
||||
|
@ -158,6 +137,67 @@ class RefundProcessor {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a refund to the PayPal order.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @param float $amount The refund amount.
|
||||
* @param string $reason The reason for the refund.
|
||||
*
|
||||
* @throws RuntimeException When operation fails.
|
||||
* @return string The PayPal refund ID.
|
||||
*/
|
||||
public function refund(
|
||||
Order $order,
|
||||
WC_Order $wc_order,
|
||||
float $amount,
|
||||
string $reason = ''
|
||||
): string {
|
||||
$payments = $this->get_payments( $order );
|
||||
|
||||
$captures = $payments->captures();
|
||||
if ( ! $captures ) {
|
||||
throw new RuntimeException( 'No capture.' );
|
||||
}
|
||||
|
||||
$capture = $captures[0];
|
||||
$refund = new RefundCapture(
|
||||
$capture,
|
||||
$capture->invoice_id(),
|
||||
$reason,
|
||||
new Amount(
|
||||
new Money( $amount, $wc_order->get_currency() )
|
||||
)
|
||||
);
|
||||
|
||||
return $this->payments_endpoint->refund( $refund );
|
||||
}
|
||||
|
||||
/**
|
||||
* Voids the authorization.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @throws RuntimeException When operation fails.
|
||||
*/
|
||||
public function void( Order $order ): void {
|
||||
$payments = $this->get_payments( $order );
|
||||
|
||||
$voidable_authorizations = array_filter(
|
||||
$payments->authorizations(),
|
||||
function ( Authorization $authorization ): bool {
|
||||
return $authorization->is_voidable();
|
||||
}
|
||||
);
|
||||
if ( ! $voidable_authorizations ) {
|
||||
throw new RuntimeException( 'No voidable authorizations.' );
|
||||
}
|
||||
|
||||
foreach ( $voidable_authorizations as $authorization ) {
|
||||
$this->payments_endpoint->void( $authorization );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the refunding mode.
|
||||
*
|
||||
|
@ -181,4 +221,24 @@ class RefundProcessor {
|
|||
|
||||
return self::REFUND_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the payments object or throws.
|
||||
*
|
||||
* @param Order $order The order.
|
||||
* @throws RuntimeException When payment not available.
|
||||
*/
|
||||
protected function get_payments( Order $order ): Payments {
|
||||
$purchase_units = $order->purchase_units();
|
||||
if ( ! $purchase_units ) {
|
||||
throw new RuntimeException( 'No purchase units.' );
|
||||
}
|
||||
|
||||
$payments = $purchase_units[0]->payments();
|
||||
if ( ! $payments ) {
|
||||
throw new RuntimeException( 'No payments.' );
|
||||
}
|
||||
|
||||
return $payments;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DisplayManager;
|
||||
|
||||
return function ( ContainerInterface $container, array $fields ): array {
|
||||
|
||||
|
@ -38,6 +40,9 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
|
||||
$module_url = $container->get( 'wcgateway.url' );
|
||||
|
||||
$display_manager = $container->get( 'wcgateway.display-manager' );
|
||||
assert( $display_manager instanceof DisplayManager );
|
||||
|
||||
$connection_fields = array(
|
||||
'ppcp_onboarading_header' => array(
|
||||
'type' => 'ppcp-text',
|
||||
|
@ -197,6 +202,11 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'toggle_manual_input' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => '<button type="button" id="ppcp[toggle_manual_input]">' . __( 'Toggle to manual credential input', 'woocommerce-paypal-payments' ) . '</button>',
|
||||
'description' => sprintf(
|
||||
'%1$s <a href="https://woocommerce.com/document/woocommerce-paypal-payments/#manual-credential-input" target="_blank">%2$s</a>',
|
||||
esc_html__( 'Further information on manual credential input:', 'woocommerce-paypal-payments' ),
|
||||
esc_html__( 'documentation', 'woocommerce-paypal-payments' )
|
||||
),
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
@ -232,7 +242,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'merchant_email_production' => array(
|
||||
'title' => __( 'Live Email address', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'type' => 'email',
|
||||
'required' => true,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The email address of your PayPal account.', 'woocommerce-paypal-payments' ),
|
||||
|
@ -245,32 +255,40 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'merchant_id_production' => array(
|
||||
'title' => __( 'Live Merchant Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'ppcp-text-input',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
'title' => __( 'Live Merchant Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The merchant id of your account. Should be exactly 13 alphanumeric uppercase letters.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 13,
|
||||
'custom_attributes' => array(
|
||||
'pattern' => '[A-Z0-9]{13}',
|
||||
'autocomplete' => 'off',
|
||||
),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'client_id_production' => array(
|
||||
'title' => __( 'Live Client Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'ppcp-text-input',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
'title' => __( 'Live Client Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->production_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
|
||||
'custom_attributes' => array(
|
||||
'autocomplete' => 'off',
|
||||
),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'client_secret_production' => array(
|
||||
'title' => __( 'Live Secret Key', 'woocommerce-paypal-payments' ),
|
||||
|
@ -290,7 +308,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'merchant_email_sandbox' => array(
|
||||
'title' => __( 'Sandbox Email address', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'type' => 'email',
|
||||
'required' => true,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The email address of your PayPal account.', 'woocommerce-paypal-payments' ),
|
||||
|
@ -303,32 +321,40 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'merchant_id_sandbox' => array(
|
||||
'title' => __( 'Sandbox Merchant Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'ppcp-text-input',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The merchant id of your account ', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
'title' => __( 'Sandbox Merchant Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The merchant id of your account. Should be exactly 13 alphanumeric uppercase letters.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 13,
|
||||
'custom_attributes' => array(
|
||||
'pattern' => '[A-Z0-9]{13}',
|
||||
'autocomplete' => 'off',
|
||||
),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'client_id_sandbox' => array(
|
||||
'title' => __( 'Sandbox Client Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'ppcp-text-input',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
'title' => __( 'Sandbox Client Id', 'woocommerce-paypal-payments' ),
|
||||
'classes' => array( State::STATE_ONBOARDED === $state->sandbox_state() ? 'onboarded' : '', 'ppcp-always-shown-element' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The client id of your api ', 'woocommerce-paypal-payments' ),
|
||||
'custom_attributes' => array(
|
||||
'autocomplete' => 'off',
|
||||
),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'client_secret_sandbox' => array(
|
||||
'title' => __( 'Sandbox Secret Key', 'woocommerce-paypal-payments' ),
|
||||
|
@ -380,30 +406,11 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'requirements' => array( 'pui_ready' ),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'tracking_enabled' => array(
|
||||
'title' => __( 'Shipment Tracking', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => $container->get( 'wcgateway.settings.tracking-label' ),
|
||||
'description' => __( 'Allows to send shipment tracking numbers to PayPal for PayPal transactions.', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'input_class' => $container->get( 'wcgateway.settings.should-disable-tracking-checkbox' ) ? array( 'ppcp-disabled-checkbox' ) : array(),
|
||||
),
|
||||
'fraudnet_enabled' => array(
|
||||
'title' => __( 'FraudNet', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'checkbox',
|
||||
'desc_tip' => true,
|
||||
'label' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__( 'Manage online risk with %1$sFraudNet%2$s.', 'woocommerce-paypal-payments' ),
|
||||
'<a href="https://woocommerce.com/document/woocommerce-paypal-payments/#FraudNet" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
'label' => $container->get( 'wcgateway.settings.fraudnet-label' ),
|
||||
'description' => __( 'FraudNet is a JavaScript library developed by PayPal and embedded into a merchant’s web page to collect browser-based data to help reduce fraud.', 'woocommerce-paypal-payments' ),
|
||||
'default' => false,
|
||||
'screens' => array(
|
||||
|
@ -411,8 +418,8 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'input_class' => $container->get( 'wcgateway.settings.should-disable-fraudnet-checkbox' ) ? array( 'ppcp-disabled-checkbox' ) : array(),
|
||||
),
|
||||
|
||||
'credentials_integration_configuration_heading' => array(
|
||||
'heading' => __( 'General integration configuration', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
|
@ -428,6 +435,20 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'</a>'
|
||||
),
|
||||
),
|
||||
'soft_descriptor' => array(
|
||||
'title' => __( 'Soft Descriptor', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The soft descriptor is the dynamic text used to construct the statement descriptor that appears on a payer\'s card statement. Text field, max value of 22 characters.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 22,
|
||||
'default' => '',
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'prefix' => array(
|
||||
'title' => __( 'Invoice prefix', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
|
@ -435,7 +456,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'description' => __( 'If you use your PayPal account with more than one installation, please use a distinct prefix to separate those installations. Please use only English letters and "-", "_" characters.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 15,
|
||||
'custom_attributes' => array(
|
||||
'pattern' => '[a-zA-Z_-]+',
|
||||
'pattern' => '[a-zA-Z_\\-]+',
|
||||
),
|
||||
'default' => ( static function (): string {
|
||||
$site_url = get_site_url( get_current_blog_id() );
|
||||
|
@ -466,6 +487,53 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'subtotal_mismatch_behavior' => array(
|
||||
'title' => __( 'Subtotal mismatch behavior', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'vertical',
|
||||
'desc_tip' => true,
|
||||
'description' => __(
|
||||
'Differences between WooCommerce and PayPal roundings may cause mismatch in order items subtotal calculations. If not handled, these mismatches will cause the PayPal transaction to fail.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
'options' => array(
|
||||
PurchaseUnitSanitizer::MODE_DITCH => __( 'Do not send line items to PayPal', 'woocommerce-paypal-payments' ),
|
||||
PurchaseUnitSanitizer::MODE_EXTRA_LINE => __( 'Add another line item', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'custom_attributes' => array(
|
||||
'data-ppcp-display' => wp_json_encode(
|
||||
array(
|
||||
$display_manager
|
||||
->rule()
|
||||
->condition_element( 'subtotal_mismatch_behavior', PurchaseUnitSanitizer::MODE_EXTRA_LINE )
|
||||
->action_visible( 'subtotal_mismatch_line_name' )
|
||||
->to_array(),
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
'subtotal_mismatch_line_name' => array(
|
||||
'title' => __( 'Subtotal mismatch line name', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The name of the extra line that will be sent to PayPal to correct the subtotal mismatch.', 'woocommerce-paypal-payments' ),
|
||||
'maxlength' => 22,
|
||||
'default' => '',
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'placeholder' => PurchaseUnitSanitizer::EXTRA_LINE_NAME,
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( $fields, $connection_fields );
|
||||
|
|
|
@ -33,11 +33,12 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
|
||||
$selected_country = $container->get( 'api.shop.country' );
|
||||
$default_messaging_flex_color = $selected_country === 'US' ? 'white-no-border' : 'white';
|
||||
|
||||
$render_preview_element = function ( string $id, string $type ): string {
|
||||
$button_message = __( 'Pay Later Button Preview', 'woocommerce-paypal-payments' );
|
||||
$messaging_message = __( 'Pay Later Messaging Preview', 'woocommerce-paypal-payments' );
|
||||
$render_preview_element = function ( string $id, string $type, string $message ): string {
|
||||
return '
|
||||
<div class="ppcp-preview ppcp-' . $type . '-preview pay-later">
|
||||
<h4>' . __( 'Preview', 'woocommerce-paypal-payments' ) . '</h4>
|
||||
<h4>' . $message . '</h4>
|
||||
<div id="' . $id . '" class="ppcp-' . $type . '-preview-inner"></div>
|
||||
</div>';
|
||||
};
|
||||
|
@ -82,7 +83,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'pay_later_button_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpPayLaterButtonPreview', 'button' ),
|
||||
'text' => $render_preview_element( 'ppcpPayLaterButtonPreview', 'button', $button_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
|
@ -245,7 +246,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'pay_later_general_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpGeneralMessagePreview', 'message' ),
|
||||
'text' => $render_preview_element( 'ppcpGeneralMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
|
@ -369,7 +370,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'pay_later_product_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpProductMessagePreview', 'message' ),
|
||||
'text' => $render_preview_element( 'ppcpProductMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
|
@ -493,7 +494,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'pay_later_cart_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpCartMessagePreview', 'message' ),
|
||||
'text' => $render_preview_element( 'ppcpCartMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
|
@ -617,7 +618,255 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'pay_later_checkout_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpCheckoutMessagePreview', 'message' ),
|
||||
'text' => $render_preview_element( 'ppcpCheckoutMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
|
||||
// Shop.
|
||||
'pay_later_shop_messaging_heading' => array(
|
||||
'heading' => __( 'Pay Later Messaging on the Shop page', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_layout' => array(
|
||||
'title' => __( 'Shop Messaging Layout', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The layout of the message.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'text' => __( 'Text', 'woocommerce-paypal-payments' ),
|
||||
'flex' => __( 'Banner', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_logo' => array(
|
||||
'title' => __( 'Shop Messaging Logo', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'inline',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'What logo the text message contains. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'primary' => __( 'Primary', 'woocommerce-paypal-payments' ),
|
||||
'alternative' => __( 'Alternative', 'woocommerce-paypal-payments' ),
|
||||
'inline' => __( 'Inline', 'woocommerce-paypal-payments' ),
|
||||
'none' => __( 'None', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_position' => array(
|
||||
'title' => __( 'Shop Messaging Logo Position', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'left',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The position of the logo. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'left' => __( 'Left', 'woocommerce-paypal-payments' ),
|
||||
'right' => __( 'Right', 'woocommerce-paypal-payments' ),
|
||||
'top' => __( 'Top', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_color' => array(
|
||||
'title' => __( 'Shop Messaging Text Color', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'black',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The color of the text. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
|
||||
'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_flex_color' => array(
|
||||
'title' => __( 'Shop Messaging Color', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => $default_messaging_flex_color,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The color of the text. Only applicable, when the layout style Banner is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
'white-no-border' => __( 'White no border', 'woocommerce-paypal-payments' ),
|
||||
'gray' => __( 'Gray', 'woocommerce-paypal-payments' ),
|
||||
'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
|
||||
'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_flex_ratio' => array(
|
||||
'title' => __( 'Shop Messaging Ratio', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => '8x1',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The width/height ratio of the banner. Only applicable, when the layout style Banner is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'1x1' => __( '1x1', 'woocommerce-paypal-payments' ),
|
||||
'1x4' => __( '1x4', 'woocommerce-paypal-payments' ),
|
||||
'8x1' => __( '8x1', 'woocommerce-paypal-payments' ),
|
||||
'20x1' => __( '20x1', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_shop_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpShopMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
|
||||
// Home.
|
||||
'pay_later_home_messaging_heading' => array(
|
||||
'heading' => __( 'Pay Later Messaging on the Home page', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'ppcp-heading',
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_layout' => array(
|
||||
'title' => __( 'Home Messaging Layout', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'text',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The layout of the message.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'text' => __( 'Text', 'woocommerce-paypal-payments' ),
|
||||
'flex' => __( 'Banner', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_logo' => array(
|
||||
'title' => __( 'Home Messaging Logo', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'inline',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'What logo the text message contains. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'primary' => __( 'Primary', 'woocommerce-paypal-payments' ),
|
||||
'alternative' => __( 'Alternative', 'woocommerce-paypal-payments' ),
|
||||
'inline' => __( 'Inline', 'woocommerce-paypal-payments' ),
|
||||
'none' => __( 'None', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_position' => array(
|
||||
'title' => __( 'Home Messaging Logo Position', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'left',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The position of the logo. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'left' => __( 'Left', 'woocommerce-paypal-payments' ),
|
||||
'right' => __( 'Right', 'woocommerce-paypal-payments' ),
|
||||
'top' => __( 'Top', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_color' => array(
|
||||
'title' => __( 'Home Messaging Text Color', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => 'black',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The color of the text. Only applicable, when the layout style Text is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
|
||||
'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_flex_color' => array(
|
||||
'title' => __( 'Home Messaging Color', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => $default_messaging_flex_color,
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The color of the text. Only applicable, when the layout style Banner is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
'white-no-border' => __( 'White no border', 'woocommerce-paypal-payments' ),
|
||||
'gray' => __( 'Gray', 'woocommerce-paypal-payments' ),
|
||||
'monochrome' => __( 'Monochrome', 'woocommerce-paypal-payments' ),
|
||||
'grayscale' => __( 'Grayscale', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_flex_ratio' => array(
|
||||
'title' => __( 'Home Messaging Ratio', 'woocommerce-paypal-payments' ),
|
||||
'type' => 'select',
|
||||
'class' => array(),
|
||||
'input_class' => array( 'wc-enhanced-select' ),
|
||||
'default' => '8x1',
|
||||
'desc_tip' => true,
|
||||
'description' => __( 'The width/height ratio of the banner. Only applicable, when the layout style Banner is used.', 'woocommerce-paypal-payments' ),
|
||||
'options' => array(
|
||||
'1x1' => __( '1x1', 'woocommerce-paypal-payments' ),
|
||||
'1x4' => __( '1x4', 'woocommerce-paypal-payments' ),
|
||||
'8x1' => __( '8x1', 'woocommerce-paypal-payments' ),
|
||||
'20x1' => __( '20x1', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
),
|
||||
'pay_later_home_message_preview' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'text' => $render_preview_element( 'ppcpHomeMessagePreview', 'message', $messaging_message ),
|
||||
'screens' => array( State::STATE_ONBOARDED ),
|
||||
'requirements' => array( 'messages' ),
|
||||
'gateway' => Settings::PAY_LATER_TAB_ID,
|
||||
|
|
|
@ -31,7 +31,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
$render_preview_element = function ( string $id ): string {
|
||||
return '
|
||||
<div class="ppcp-preview ppcp-button-preview">
|
||||
<h4>' . __( 'Preview', 'woocommerce-paypal-payments' ) . '</h4>
|
||||
<h4>' . __( 'Button Styling Preview', 'woocommerce-paypal-payments' ) . '</h4>
|
||||
<div id="' . $id . '" class="ppcp-button-preview-inner"></div>
|
||||
</div>';
|
||||
};
|
||||
|
@ -49,7 +49,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'description' => sprintf(
|
||||
// translators: %1$s and %2$s are the opening and closing of HTML <a> tag.
|
||||
__(
|
||||
'Customize the appearance of the PayPal smart buttons on the
|
||||
'Customize the appearance of the PayPal smart buttons on the
|
||||
%1$sCheckout page%5$s, %2$sSingle Product Page%5$s, %3$sCart page%5$s or on %4$sMini Cart%5$s.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
|
@ -174,6 +174,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
@ -319,6 +320,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
@ -458,6 +460,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
@ -597,6 +600,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
@ -736,6 +740,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'blue' => __( 'Blue', 'woocommerce-paypal-payments' ),
|
||||
'silver' => __( 'Silver', 'woocommerce-paypal-payments' ),
|
||||
'black' => __( 'Black', 'woocommerce-paypal-payments' ),
|
||||
'white' => __( 'White', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
|
|
|
@ -60,7 +60,7 @@ class HeaderRenderer {
|
|||
|
||||
return '
|
||||
<div class="ppcp-settings-page-header">
|
||||
<img alt="PayPal" src="' . esc_url( $this->module_url ) . 'assets/images/paypal.png"/>
|
||||
<img alt="PayPal" src="' . esc_url( $this->module_url ) . 'assets/images/paypal.png" style="max-height: 30px" />
|
||||
<h4> <span class="ppcp-inline-only">-</span> ' . __( 'The all-in-one checkout solution for WooCommerce', 'woocommerce-paypal-payments' ) . '</h4>
|
||||
<a class="button" target="_blank" href="https://woocommerce.com/document/woocommerce-paypal-payments/">'
|
||||
. __( 'Documentation', 'woocommerce-paypal-payments' ) .
|
||||
|
@ -77,6 +77,8 @@ class HeaderRenderer {
|
|||
'</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="ppcp-notice-wrapper"></div>
|
||||
';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,16 @@ declare( strict_types=1 );
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\MessagesApply;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CardButtonGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\OXXO\OXXOGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PayUponInvoiceGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus;
|
||||
|
||||
/**
|
||||
* Class SectionsRenderer
|
||||
|
@ -26,13 +34,6 @@ class SectionsRenderer {
|
|||
*/
|
||||
protected $page_id;
|
||||
|
||||
/**
|
||||
* Key - page/gateway ID, value - displayed text.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $sections;
|
||||
|
||||
/**
|
||||
* The onboarding state.
|
||||
*
|
||||
|
@ -40,17 +41,65 @@ class SectionsRenderer {
|
|||
*/
|
||||
private $state;
|
||||
|
||||
/**
|
||||
* The DCC product status
|
||||
*
|
||||
* @var DCCProductStatus
|
||||
*/
|
||||
private $dcc_product_status;
|
||||
|
||||
/**
|
||||
* The DCC applies
|
||||
*
|
||||
* @var DccApplies
|
||||
*/
|
||||
private $dcc_applies;
|
||||
|
||||
/**
|
||||
* The messages apply.
|
||||
*
|
||||
* @var MessagesApply
|
||||
*/
|
||||
private $messages_apply;
|
||||
|
||||
/**
|
||||
* The PUI product status.
|
||||
*
|
||||
* @var PayUponInvoiceProductStatus
|
||||
*/
|
||||
private $pui_product_status;
|
||||
|
||||
/**
|
||||
* SectionsRenderer constructor.
|
||||
*
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param array<string, string> $sections Key - page/gateway ID, value - displayed text.
|
||||
* @param State $state The onboarding state.
|
||||
*/
|
||||
public function __construct( string $page_id, array $sections, State $state ) {
|
||||
$this->page_id = $page_id;
|
||||
$this->sections = $sections;
|
||||
$this->state = $state;
|
||||
|
||||
/**
|
||||
* SectionsRenderer constructor.
|
||||
*
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param State $state The onboarding state.
|
||||
* @param DCCProductStatus $dcc_product_status The DCC product status.
|
||||
* @param DccApplies $dcc_applies The DCC applies.
|
||||
* @param MessagesApply $messages_apply The Messages apply.
|
||||
* @param PayUponInvoiceProductStatus $pui_product_status The PUI product status.
|
||||
*/
|
||||
public function __construct(
|
||||
string $page_id,
|
||||
State $state,
|
||||
DCCProductStatus $dcc_product_status,
|
||||
DccApplies $dcc_applies,
|
||||
MessagesApply $messages_apply,
|
||||
PayUponInvoiceProductStatus $pui_product_status
|
||||
) {
|
||||
$this->page_id = $page_id;
|
||||
$this->state = $state;
|
||||
$this->dcc_product_status = $dcc_product_status;
|
||||
$this->dcc_applies = $dcc_applies;
|
||||
$this->messages_apply = $messages_apply;
|
||||
$this->pui_product_status = $pui_product_status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,6 +115,8 @@ class SectionsRenderer {
|
|||
|
||||
/**
|
||||
* Renders the Sections tab.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(): string {
|
||||
if ( ! $this->should_render() ) {
|
||||
|
@ -74,8 +125,8 @@ class SectionsRenderer {
|
|||
|
||||
$html = '<nav class="nav-tab-wrapper woo-nav-tab-wrapper">';
|
||||
|
||||
foreach ( $this->sections as $id => $label ) {
|
||||
$url = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . $id );
|
||||
foreach ( $this->sections() as $id => $label ) {
|
||||
$url = admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=' . (string) $id );
|
||||
if ( in_array( $id, array( Settings::CONNECTION_TAB_ID, CreditCardGateway::ID, Settings::PAY_LATER_TAB_ID ), true ) ) {
|
||||
// We need section=ppcp-gateway for the webhooks page because it is not a gateway,
|
||||
// and for DCC because otherwise it will not render the page if gateway is not available (country/currency).
|
||||
|
@ -89,4 +140,46 @@ class SectionsRenderer {
|
|||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns sections as Key - page/gateway ID, value - displayed text.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function sections(): array {
|
||||
$sections = array(
|
||||
Settings::CONNECTION_TAB_ID => __( 'Connection', 'woocommerce-paypal-payments' ),
|
||||
PayPalGateway::ID => __( 'Standard Payments', 'woocommerce-paypal-payments' ),
|
||||
Settings::PAY_LATER_TAB_ID => __( 'Pay Later', 'woocommerce-paypal-payments' ),
|
||||
CreditCardGateway::ID => __( 'Advanced Card Processing', 'woocommerce-paypal-payments' ),
|
||||
CardButtonGateway::ID => __( 'Standard Card Button', 'woocommerce-paypal-payments' ),
|
||||
OXXOGateway::ID => __( 'OXXO', 'woocommerce-paypal-payments' ),
|
||||
PayUponInvoiceGateway::ID => __( 'Pay upon Invoice', 'woocommerce-paypal-payments' ),
|
||||
);
|
||||
|
||||
// Remove for all not registered in WC gateways that cannot render anything in this case.
|
||||
$gateways = WC()->payment_gateways->payment_gateways();
|
||||
foreach ( array_diff(
|
||||
array_keys( $sections ),
|
||||
array( Settings::CONNECTION_TAB_ID, PayPalGateway::ID, CreditCardGateway::ID, Settings::PAY_LATER_TAB_ID )
|
||||
) as $id ) {
|
||||
if ( ! isset( $gateways[ $id ] ) ) {
|
||||
unset( $sections[ $id ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $this->dcc_product_status->dcc_is_active() || ! $this->dcc_applies->for_country_currency() ) {
|
||||
unset( $sections['ppcp-credit-card-gateway'] );
|
||||
}
|
||||
|
||||
if ( ! $this->messages_apply->for_country() ) {
|
||||
unset( $sections[ Settings::PAY_LATER_TAB_ID ] );
|
||||
}
|
||||
|
||||
if ( ! $this->pui_product_status->pui_is_active() ) {
|
||||
unset( $sections[ PayUponInvoiceGateway::ID ] );
|
||||
}
|
||||
|
||||
return $sections;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,13 +35,22 @@ class Settings implements ContainerInterface {
|
|||
*/
|
||||
protected $default_button_locations;
|
||||
|
||||
/**
|
||||
* The default ACDC gateway title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $default_dcc_gateway_title;
|
||||
|
||||
/**
|
||||
* Settings constructor.
|
||||
*
|
||||
* @param string[] $default_button_locations The list of selected default button locations.
|
||||
* @param string $default_dcc_gateway_title The default ACDC gateway title.
|
||||
*/
|
||||
public function __construct( array $default_button_locations ) {
|
||||
$this->default_button_locations = $default_button_locations;
|
||||
public function __construct( array $default_button_locations, string $default_dcc_gateway_title ) {
|
||||
$this->default_button_locations = $default_button_locations;
|
||||
$this->default_dcc_gateway_title = $default_dcc_gateway_title;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +125,7 @@ class Settings implements ContainerInterface {
|
|||
'pay_later_button_locations' => $this->default_button_locations,
|
||||
'pay_later_messaging_locations' => $this->default_button_locations,
|
||||
'brand_name' => get_bloginfo( 'name' ),
|
||||
'dcc_gateway_title' => __( 'Credit Cards', 'woocommerce-paypal-payments' ),
|
||||
'dcc_gateway_title' => $this->default_dcc_gateway_title,
|
||||
'dcc_gateway_description' => __(
|
||||
'Pay with your credit card.',
|
||||
'woocommerce-paypal-payments'
|
||||
|
|
|
@ -9,16 +9,22 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Entity\Message;
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Http\RedirectorInterface;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Helper\OnboardingUrl;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus;
|
||||
use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\WooCommerce\Logging\Logger\NullLogger;
|
||||
|
||||
/**
|
||||
* Class SettingsListener
|
||||
|
@ -111,20 +117,66 @@ class SettingsListener {
|
|||
*/
|
||||
protected $dcc_status_cache;
|
||||
|
||||
/**
|
||||
* The HTTP redirector.
|
||||
*
|
||||
* @var RedirectorInterface
|
||||
*/
|
||||
protected $redirector;
|
||||
|
||||
/**
|
||||
* Max onboarding URL retries.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $onboarding_max_retries = 5;
|
||||
|
||||
/**
|
||||
* Delay between onboarding URL retries.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $onboarding_retry_delay = 2;
|
||||
|
||||
/**
|
||||
* Partner merchant ID production.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $partner_merchant_id_production;
|
||||
|
||||
/**
|
||||
* Partner merchant ID sandbox.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $partner_merchant_id_sandbox;
|
||||
|
||||
/**
|
||||
* The logger.
|
||||
*
|
||||
* @var LoggerInterface
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* SettingsListener constructor.
|
||||
*
|
||||
* @param Settings $settings The settings.
|
||||
* @param array $setting_fields The setting fields.
|
||||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param State $state The state.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param Cache $signup_link_cache The signup link cache.
|
||||
* @param array $signup_link_ids Signup link ids.
|
||||
* @param Cache $pui_status_cache The PUI status cache.
|
||||
* @param Cache $dcc_status_cache The DCC status cache.
|
||||
* @param Settings $settings The settings.
|
||||
* @param array $setting_fields The setting fields.
|
||||
* @param WebhookRegistrar $webhook_registrar The Webhook Registrar.
|
||||
* @param Cache $cache The Cache.
|
||||
* @param State $state The state.
|
||||
* @param Bearer $bearer The bearer.
|
||||
* @param string $page_id ID of the current PPCP gateway settings page, or empty if it is not such page.
|
||||
* @param Cache $signup_link_cache The signup link cache.
|
||||
* @param array $signup_link_ids Signup link ids.
|
||||
* @param Cache $pui_status_cache The PUI status cache.
|
||||
* @param Cache $dcc_status_cache The DCC status cache.
|
||||
* @param RedirectorInterface $redirector The HTTP redirector.
|
||||
* @param string $partner_merchant_id_production Partner merchant ID production.
|
||||
* @param string $partner_merchant_id_sandbox Partner merchant ID sandbox.
|
||||
* @param ?LoggerInterface $logger The logger.
|
||||
*/
|
||||
public function __construct(
|
||||
Settings $settings,
|
||||
|
@ -137,27 +189,34 @@ class SettingsListener {
|
|||
Cache $signup_link_cache,
|
||||
array $signup_link_ids,
|
||||
Cache $pui_status_cache,
|
||||
Cache $dcc_status_cache
|
||||
Cache $dcc_status_cache,
|
||||
RedirectorInterface $redirector,
|
||||
string $partner_merchant_id_production,
|
||||
string $partner_merchant_id_sandbox,
|
||||
LoggerInterface $logger = null
|
||||
) {
|
||||
|
||||
$this->settings = $settings;
|
||||
$this->setting_fields = $setting_fields;
|
||||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
$this->bearer = $bearer;
|
||||
$this->page_id = $page_id;
|
||||
$this->signup_link_cache = $signup_link_cache;
|
||||
$this->signup_link_ids = $signup_link_ids;
|
||||
$this->pui_status_cache = $pui_status_cache;
|
||||
$this->dcc_status_cache = $dcc_status_cache;
|
||||
$this->settings = $settings;
|
||||
$this->setting_fields = $setting_fields;
|
||||
$this->webhook_registrar = $webhook_registrar;
|
||||
$this->cache = $cache;
|
||||
$this->state = $state;
|
||||
$this->bearer = $bearer;
|
||||
$this->page_id = $page_id;
|
||||
$this->signup_link_cache = $signup_link_cache;
|
||||
$this->signup_link_ids = $signup_link_ids;
|
||||
$this->pui_status_cache = $pui_status_cache;
|
||||
$this->dcc_status_cache = $dcc_status_cache;
|
||||
$this->redirector = $redirector;
|
||||
$this->partner_merchant_id_production = $partner_merchant_id_production;
|
||||
$this->partner_merchant_id_sandbox = $partner_merchant_id_sandbox;
|
||||
$this->logger = $logger ?: new NullLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens if the merchant ID should be updated.
|
||||
*/
|
||||
public function listen_for_merchant_id() {
|
||||
|
||||
public function listen_for_merchant_id(): void {
|
||||
if ( ! $this->is_valid_site_request() ) {
|
||||
return;
|
||||
}
|
||||
|
@ -167,17 +226,59 @@ class SettingsListener {
|
|||
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
*/
|
||||
if ( ! isset( $_GET['merchantIdInPayPal'] ) || ! isset( $_GET['merchantId'] ) ) {
|
||||
if ( ! isset( $_GET['merchantIdInPayPal'] ) || ! isset( $_GET['merchantId'] ) || ! isset( $_GET['ppcpToken'] ) ) {
|
||||
return;
|
||||
}
|
||||
$merchant_id = sanitize_text_field( wp_unslash( $_GET['merchantIdInPayPal'] ) );
|
||||
$merchant_email = sanitize_text_field( wp_unslash( $_GET['merchantId'] ) );
|
||||
|
||||
$merchant_id = sanitize_text_field( wp_unslash( $_GET['merchantIdInPayPal'] ) );
|
||||
if ( $merchant_id === $this->partner_merchant_id_production || $merchant_id === $this->partner_merchant_id_sandbox ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$merchant_email = $this->sanitize_onboarding_email( sanitize_text_field( wp_unslash( $_GET['merchantId'] ) ) );
|
||||
$onboarding_token = sanitize_text_field( wp_unslash( $_GET['ppcpToken'] ) );
|
||||
$retry_count = isset( $_GET['ppcpRetry'] ) ? ( (int) sanitize_text_field( wp_unslash( $_GET['ppcpRetry'] ) ) ) : 0;
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
$this->settings->set( 'merchant_id', $merchant_id );
|
||||
$this->settings->set( 'merchant_email', $merchant_email );
|
||||
|
||||
// If no client_id is present we will try to wait for PayPal to invoke LoginSellerEndpoint.
|
||||
if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
|
||||
|
||||
// Try at most {onboarding_max_retries} times ({onboarding_retry_delay} seconds delay). Then give up and just fill the merchant fields like before.
|
||||
if ( $retry_count < $this->onboarding_max_retries ) {
|
||||
|
||||
if ( $this->onboarding_retry_delay > 0 ) {
|
||||
sleep( $this->onboarding_retry_delay );
|
||||
}
|
||||
|
||||
$retry_count++;
|
||||
$this->logger->info( 'Retrying onboarding return URL, retry nr: ' . ( (string) $retry_count ) );
|
||||
$redirect_url = add_query_arg( 'ppcpRetry', $retry_count );
|
||||
$this->redirector->redirect( $redirect_url );
|
||||
}
|
||||
}
|
||||
|
||||
// Process token validation.
|
||||
$onboarding_token_sample = ( (string) substr( $onboarding_token, 0, 2 ) ) . '...' . ( (string) substr( $onboarding_token, -6 ) );
|
||||
$this->logger->debug( 'Validating onboarding ppcpToken: ' . $onboarding_token_sample );
|
||||
|
||||
if ( ! OnboardingUrl::validate_token_and_delete( $this->signup_link_cache, $onboarding_token, get_current_user_id() ) ) {
|
||||
if ( OnboardingUrl::validate_previous_token( $this->signup_link_cache, $onboarding_token, get_current_user_id() ) ) {
|
||||
// It's a valid token used previously, don't do anything but silently redirect.
|
||||
$this->logger->info( 'Validated previous token, silently redirecting: ' . $onboarding_token_sample );
|
||||
$this->onboarding_redirect();
|
||||
} else {
|
||||
$this->logger->error( 'Failed to validate onboarding ppcpToken: ' . $onboarding_token_sample );
|
||||
$this->onboarding_redirect( false );
|
||||
}
|
||||
}
|
||||
|
||||
$this->logger->info( 'Validated onboarding ppcpToken: ' . $onboarding_token_sample );
|
||||
|
||||
// Save the merchant data.
|
||||
$is_sandbox = $this->settings->has( 'sandbox_on' ) && $this->settings->get( 'sandbox_on' );
|
||||
if ( $is_sandbox ) {
|
||||
$this->settings->set( 'merchant_id_sandbox', $merchant_id );
|
||||
|
@ -193,20 +294,48 @@ class SettingsListener {
|
|||
*/
|
||||
do_action( 'woocommerce_paypal_payments_onboarding_before_redirect' );
|
||||
|
||||
/**
|
||||
* The URL opened at the end of onboarding after saving the merchant ID/email.
|
||||
*/
|
||||
$redirect_url = apply_filters( 'woocommerce_paypal_payments_onboarding_redirect_url', admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway&ppcp-tab=' . Settings::CONNECTION_TAB_ID ) );
|
||||
// If after all the retry redirects there still isn't a valid client_id then just send an error.
|
||||
if ( ! $this->settings->has( 'client_id' ) || ! $this->settings->get( 'client_id' ) ) {
|
||||
$redirect_url = add_query_arg( 'ppcp-onboarding-error', '1', $redirect_url );
|
||||
$this->onboarding_redirect( false );
|
||||
}
|
||||
|
||||
wp_safe_redirect( $redirect_url, 302 );
|
||||
exit;
|
||||
$this->onboarding_redirect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the onboarding email.
|
||||
*
|
||||
* @param string $email The onboarding email.
|
||||
* @return string
|
||||
*/
|
||||
private function sanitize_onboarding_email( string $email ): string {
|
||||
return str_replace( ' ', '+', $email );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect to the onboarding URL.
|
||||
*
|
||||
* @param bool $success Should redirect to the success or error URL.
|
||||
* @return void
|
||||
*/
|
||||
private function onboarding_redirect( bool $success = true ): void {
|
||||
$redirect_url = $this->get_onboarding_redirect_url();
|
||||
|
||||
if ( ! $success ) {
|
||||
$redirect_url = add_query_arg( 'ppcp-onboarding-error', '1', $redirect_url );
|
||||
$this->logger->info( 'Redirect ERROR: ' . $redirect_url );
|
||||
} else {
|
||||
$redirect_url = remove_query_arg( 'ppcp-onboarding-error', $redirect_url );
|
||||
$this->logger->info( 'Redirect OK: ' . $redirect_url );
|
||||
}
|
||||
|
||||
$this->redirector->redirect( $redirect_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent enabling both Pay Later messaging and PayPal vaulting
|
||||
*
|
||||
* @throws RuntimeException When API request fails.
|
||||
*/
|
||||
public function listen_for_vaulting_enabled() {
|
||||
if ( ! $this->is_valid_site_request() || State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
||||
|
@ -217,23 +346,16 @@ class SettingsListener {
|
|||
$token = $this->bearer->bearer();
|
||||
if ( ! $token->vaulting_available() ) {
|
||||
$this->settings->set( 'vault_enabled', false );
|
||||
$this->settings->set( 'vault_enabled_dcc', false );
|
||||
$this->settings->persist();
|
||||
return;
|
||||
}
|
||||
} catch ( RuntimeException $exception ) {
|
||||
$this->settings->set( 'vault_enabled', false );
|
||||
$this->settings->set( 'vault_enabled_dcc', false );
|
||||
$this->settings->persist();
|
||||
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post( __( 'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.', 'woocommerce-paypal-payments' ) )
|
||||
);
|
||||
}
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -242,7 +364,20 @@ class SettingsListener {
|
|||
* phpcs:disable WordPress.Security.NonceVerification.Missing
|
||||
* phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
*/
|
||||
if ( ! isset( $_POST['ppcp']['vault_enabled'] ) ) {
|
||||
$vault_enabled = wc_clean( wp_unslash( $_POST['ppcp']['vault_enabled'] ?? '' ) );
|
||||
$subscription_mode = wc_clean( wp_unslash( $_POST['ppcp']['subscriptions_mode'] ?? '' ) );
|
||||
|
||||
if ( $subscription_mode === 'vaulting_api' && $vault_enabled !== '1' ) {
|
||||
$this->settings->set( 'vault_enabled', true );
|
||||
$this->settings->persist();
|
||||
}
|
||||
|
||||
if ( $subscription_mode === 'disable_paypal_subscriptions' && $vault_enabled === '1' ) {
|
||||
$this->settings->set( 'vault_enabled', false );
|
||||
$this->settings->persist();
|
||||
}
|
||||
|
||||
if ( $vault_enabled !== '1' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -303,6 +438,7 @@ class SettingsListener {
|
|||
if ( self::CREDENTIALS_UNCHANGED !== $credentials_change_status ) {
|
||||
$this->settings->set( 'products_dcc_enabled', null );
|
||||
$this->settings->set( 'products_pui_enabled', null );
|
||||
do_action( 'woocommerce_paypal_payments_clear_apm_product_status', $this->settings );
|
||||
}
|
||||
|
||||
if ( in_array(
|
||||
|
@ -313,9 +449,7 @@ class SettingsListener {
|
|||
$this->webhook_registrar->unregister();
|
||||
|
||||
foreach ( $this->signup_link_ids as $key ) {
|
||||
if ( $this->signup_link_cache->has( $key ) ) {
|
||||
$this->signup_link_cache->delete( $key );
|
||||
}
|
||||
( new OnboardingUrl( $this->signup_link_cache, $key, get_current_user_id() ) )->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,16 +459,6 @@ class SettingsListener {
|
|||
}
|
||||
$this->settings->persist();
|
||||
|
||||
if ( $credentials_change_status ) {
|
||||
if ( in_array(
|
||||
$credentials_change_status,
|
||||
array( self::CREDENTIALS_ADDED, self::CREDENTIALS_CHANGED ),
|
||||
true
|
||||
) ) {
|
||||
$this->webhook_registrar->register();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->cache->has( PayPalBearer::CACHE_KEY ) ) {
|
||||
$this->cache->delete( PayPalBearer::CACHE_KEY );
|
||||
}
|
||||
|
@ -347,16 +471,45 @@ class SettingsListener {
|
|||
$this->dcc_status_cache->delete( DCCProductStatus::DCC_STATUS_CACHE_KEY );
|
||||
}
|
||||
|
||||
/**
|
||||
* The hook fired during listening the request so a module can remove also the cache or other logic.
|
||||
*/
|
||||
do_action( 'woocommerce_paypal_payments_on_listening_request' );
|
||||
|
||||
$ppcp_reference_transaction_enabled = get_transient( 'ppcp_reference_transaction_enabled' ) ?? '';
|
||||
if ( $ppcp_reference_transaction_enabled ) {
|
||||
delete_transient( 'ppcp_reference_transaction_enabled' );
|
||||
}
|
||||
|
||||
$redirect_url = false;
|
||||
if ( $credentials_change_status && self::CREDENTIALS_UNCHANGED !== $credentials_change_status ) {
|
||||
$redirect_url = $this->get_onboarding_redirect_url();
|
||||
}
|
||||
|
||||
if ( isset( $_GET['ppcp-onboarding-error'] ) ) {
|
||||
$url = remove_query_arg( 'ppcp-onboarding-error' );
|
||||
wp_safe_redirect( $url, 302 );
|
||||
exit;
|
||||
$redirect_url = remove_query_arg( 'ppcp-onboarding-error', $redirect_url );
|
||||
}
|
||||
|
||||
if ( $redirect_url ) {
|
||||
$this->redirector->redirect( $redirect_url );
|
||||
}
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL opened at the end of onboarding.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_onboarding_redirect_url(): string {
|
||||
/**
|
||||
* The URL opened at the end of onboarding after saving the merchant ID/email.
|
||||
*/
|
||||
return apply_filters( 'woocommerce_paypal_payments_onboarding_redirect_url', admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway&ppcp-tab=' . Settings::CONNECTION_TAB_ID ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual used client credentials are stored in 'client_secret', 'client_id', 'merchant_id' and 'merchant_email'.
|
||||
* This method populates those fields depending on the sandbox status.
|
||||
|
@ -369,10 +522,18 @@ class SettingsListener {
|
|||
if ( ! isset( $settings['client_id_sandbox'] ) && ! isset( $settings['client_id_production'] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
$is_sandbox = isset( $settings['sandbox_on'] ) && $settings['sandbox_on'];
|
||||
$settings['client_id'] = $is_sandbox ? $settings['client_id_sandbox'] : $settings['client_id_production'];
|
||||
$settings['client_secret'] = $is_sandbox ? $settings['client_secret_sandbox'] : $settings['client_secret_production'];
|
||||
$settings['merchant_id'] = $is_sandbox ? $settings['merchant_id_sandbox'] : $settings['merchant_id_production'];
|
||||
$is_sandbox = isset( $settings['sandbox_on'] ) && $settings['sandbox_on'];
|
||||
$settings['client_id'] = $is_sandbox ? $settings['client_id_sandbox'] : $settings['client_id_production'];
|
||||
$settings['client_secret'] = $is_sandbox ? $settings['client_secret_sandbox'] : $settings['client_secret_production'];
|
||||
|
||||
if ( $settings['merchant_id_sandbox'] === $this->partner_merchant_id_sandbox || $settings['merchant_id_sandbox'] === $this->partner_merchant_id_production ) {
|
||||
$settings['merchant_id_sandbox'] = '';
|
||||
}
|
||||
if ( $settings['merchant_id_production'] === $this->partner_merchant_id_sandbox || $settings['merchant_id_sandbox'] === $this->partner_merchant_id_production ) {
|
||||
$settings['merchant_id_production'] = '';
|
||||
}
|
||||
$settings['merchant_id'] = $is_sandbox ? $settings['merchant_id_sandbox'] : $settings['merchant_id_production'];
|
||||
|
||||
$settings['merchant_email'] = $is_sandbox ? $settings['merchant_email_sandbox'] : $settings['merchant_email_production'];
|
||||
return $settings;
|
||||
}
|
||||
|
@ -439,7 +600,7 @@ class SettingsListener {
|
|||
break;
|
||||
case 'text':
|
||||
case 'number':
|
||||
case 'ppcp-text-input':
|
||||
case 'email':
|
||||
$settings[ $key ] = isset( $raw_data[ $key ] ) ? wp_kses_post( $raw_data[ $key ] ) : '';
|
||||
break;
|
||||
case 'ppcp-password':
|
||||
|
@ -515,6 +676,8 @@ class SettingsListener {
|
|||
|
||||
/**
|
||||
* Prevent enabling tracking if it is not enabled for merchant account.
|
||||
*
|
||||
* @throws RuntimeException When API request fails.
|
||||
*/
|
||||
public function listen_for_tracking_enabled(): void {
|
||||
if ( State::STATE_ONBOARDED !== $this->state->current_state() ) {
|
||||
|
@ -532,16 +695,18 @@ class SettingsListener {
|
|||
$this->settings->set( 'tracking_enabled', false );
|
||||
$this->settings->persist();
|
||||
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post( __( 'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.', 'woocommerce-paypal-payments' ) )
|
||||
);
|
||||
}
|
||||
);
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles onboarding URLs deletion
|
||||
*/
|
||||
public function listen_for_uninstall(): void {
|
||||
// Clear onboarding links from cache.
|
||||
foreach ( $this->signup_link_ids as $key ) {
|
||||
( new OnboardingUrl( $this->signup_link_cache, $key, get_current_user_id() ) )->delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -243,39 +243,6 @@ class SettingsRenderer {
|
|||
return $html;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Renders the text input field.
|
||||
*
|
||||
* @param string $field The current field HTML.
|
||||
* @param string $key The current key.
|
||||
* @param array $config The configuration array.
|
||||
* @param string $value The current value.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_text_input( $field, $key, $config, $value ): string {
|
||||
|
||||
if ( 'ppcp-text-input' !== $config['type'] ) {
|
||||
return $field;
|
||||
}
|
||||
|
||||
$html = sprintf(
|
||||
'<input
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
class="%s"
|
||||
name="%s"
|
||||
value="%s"
|
||||
>',
|
||||
esc_attr( implode( ' ', $config['class'] ) ),
|
||||
esc_attr( $key ),
|
||||
esc_attr( $value )
|
||||
);
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the heading field.
|
||||
*
|
||||
|
|
|
@ -9,6 +9,11 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\WcGateway;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Throwable;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
||||
use WooCommerce\PayPalCommerce\Subscription\Helper\SubscriptionHelper;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WC_Order;
|
||||
|
@ -16,7 +21,6 @@ use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Capture;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\OrderStatus;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\DccApplies;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Repository\PayPalRequestIdRepository;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\FeesRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Admin\OrderTablePaymentStatusColumn;
|
||||
|
@ -29,12 +33,14 @@ use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\GatewayRepository;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DCCProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\PayUponInvoiceProductStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\SettingsStatus;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\GatewayWithoutPayPalAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\UnsupportedCurrencyAdminNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\AuthorizedPaymentsProcessor;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\HeaderRenderer;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\SectionsRenderer;
|
||||
|
@ -149,6 +155,12 @@ class WCGatewayModule implements ModuleInterface {
|
|||
if ( ! $wc_order instanceof WC_Order ) {
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* The filter can be used to remove the rows with PayPal fees in WC orders.
|
||||
*/
|
||||
if ( ! apply_filters( 'woocommerce_paypal_payments_show_fees_on_order_admin_page', true, $wc_order ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $fees_renderer->render( $wc_order );
|
||||
|
@ -169,9 +181,11 @@ class WCGatewayModule implements ModuleInterface {
|
|||
$c->get( 'button.client_id_for_admin' ),
|
||||
$c->get( 'api.shop.currency' ),
|
||||
$c->get( 'api.shop.country' ),
|
||||
$c->get( 'onboarding.environment' ),
|
||||
$settings_status->is_pay_later_button_enabled(),
|
||||
$settings->has( 'disable_funding' ) ? $settings->get( 'disable_funding' ) : array(),
|
||||
$c->get( 'wcgateway.all-funding-sources' )
|
||||
$c->get( 'wcgateway.settings.funding-sources' ),
|
||||
$c->get( 'wcgateway.is-ppcp-settings-page' )
|
||||
);
|
||||
$assets->register_assets();
|
||||
}
|
||||
|
@ -186,6 +200,13 @@ class WCGatewayModule implements ModuleInterface {
|
|||
$notices[] = $connect_message;
|
||||
}
|
||||
|
||||
$notice = $c->get( 'wcgateway.notice.currency-unsupported' );
|
||||
assert( $notice instanceof UnsupportedCurrencyAdminNotice );
|
||||
$unsupported_currency_message = $notice->unsupported_currency_message();
|
||||
if ( $unsupported_currency_message ) {
|
||||
$notices[] = $unsupported_currency_message;
|
||||
}
|
||||
|
||||
foreach ( array(
|
||||
$c->get( 'wcgateway.notice.dcc-without-paypal' ),
|
||||
$c->get( 'wcgateway.notice.card-button-without-paypal' ),
|
||||
|
@ -215,7 +236,6 @@ class WCGatewayModule implements ModuleInterface {
|
|||
'woocommerce_paypal_commerce_gateway_deactivate',
|
||||
static function () use ( $c ) {
|
||||
delete_option( Settings::KEY );
|
||||
delete_option( PayPalRequestIdRepository::KEY );
|
||||
delete_option( 'woocommerce_' . PayPalGateway::ID . '_settings' );
|
||||
delete_option( 'woocommerce_' . CreditCardGateway::ID . '_settings' );
|
||||
}
|
||||
|
@ -237,6 +257,8 @@ class WCGatewayModule implements ModuleInterface {
|
|||
add_action(
|
||||
'woocommerce_paypal_payments_gateway_migrate',
|
||||
static function () use ( $c ) {
|
||||
delete_option( 'ppcp-request-ids' );
|
||||
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
||||
|
@ -252,7 +274,35 @@ class WCGatewayModule implements ModuleInterface {
|
|||
);
|
||||
|
||||
add_action(
|
||||
'init',
|
||||
'woocommerce_paypal_payments_gateway_migrate_on_update',
|
||||
static function() use ( $c ) {
|
||||
$dcc_status_cache = $c->get( 'dcc.status-cache' );
|
||||
assert( $dcc_status_cache instanceof Cache );
|
||||
$pui_status_cache = $c->get( 'pui.status-cache' );
|
||||
assert( $pui_status_cache instanceof Cache );
|
||||
|
||||
$dcc_status_cache->delete( DCCProductStatus::DCC_STATUS_CACHE_KEY );
|
||||
$pui_status_cache->delete( PayUponInvoiceProductStatus::PUI_STATUS_CACHE_KEY );
|
||||
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
$settings->set( 'products_dcc_enabled', false );
|
||||
$settings->set( 'products_pui_enabled', false );
|
||||
$settings->persist();
|
||||
do_action( 'woocommerce_paypal_payments_clear_apm_product_status', $settings );
|
||||
|
||||
// Update caches.
|
||||
$dcc_status = $c->get( 'wcgateway.helper.dcc-product-status' );
|
||||
assert( $dcc_status instanceof DCCProductStatus );
|
||||
$dcc_status->dcc_is_active();
|
||||
|
||||
$pui_status = $c->get( 'wcgateway.pay-upon-invoice-product-status' );
|
||||
assert( $pui_status instanceof PayUponInvoiceProductStatus );
|
||||
$pui_status->pui_is_active();
|
||||
}
|
||||
);
|
||||
|
||||
add_action(
|
||||
'wp_loaded',
|
||||
function () use ( $c ) {
|
||||
if ( 'DE' === $c->get( 'api.shop.country' ) ) {
|
||||
( $c->get( 'wcgateway.pay-upon-invoice' ) )->init();
|
||||
|
@ -294,12 +344,80 @@ class WCGatewayModule implements ModuleInterface {
|
|||
);
|
||||
|
||||
add_action(
|
||||
'wc_ajax_ppc-oxxo',
|
||||
'woocommerce_order_status_changed',
|
||||
static function ( int $order_id, string $from, string $to ) use ( $c ) {
|
||||
$wc_order = wc_get_order( $order_id );
|
||||
if ( ! $wc_order instanceof WC_Order ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings = $c->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof ContainerInterface );
|
||||
|
||||
if ( ! $settings->has( 'capture_on_status_change' ) || ! $settings->get( 'capture_on_status_change' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$gateway_repository = $c->get( 'wcgateway.gateway-repository' );
|
||||
assert( $gateway_repository instanceof GatewayRepository );
|
||||
|
||||
// Only allow to proceed if the payment method is one of our Gateways.
|
||||
if ( ! $gateway_repository->exists( $wc_order->get_payment_method() ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$intent = strtoupper( (string) $wc_order->get_meta( PayPalGateway::INTENT_META_KEY ) );
|
||||
$captured = wc_string_to_bool( $wc_order->get_meta( AuthorizedPaymentsProcessor::CAPTURED_META_KEY ) );
|
||||
if ( $intent !== 'AUTHORIZE' || $captured ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The filter returning the WC order statuses which trigger capturing of payment authorization.
|
||||
*/
|
||||
$capture_statuses = apply_filters( 'woocommerce_paypal_payments_auto_capture_statuses', array( 'processing', 'completed' ), $wc_order );
|
||||
if ( ! in_array( $to, $capture_statuses, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$authorized_payment_processor = $c->get( 'wcgateway.processor.authorized-payments' );
|
||||
assert( $authorized_payment_processor instanceof AuthorizedPaymentsProcessor );
|
||||
|
||||
try {
|
||||
if ( $authorized_payment_processor->capture_authorized_payment( $wc_order ) ) {
|
||||
return;
|
||||
}
|
||||
} catch ( Throwable $error ) {
|
||||
$logger = $c->get( 'woocommerce.logger.woocommerce' );
|
||||
assert( $logger instanceof LoggerInterface );
|
||||
$logger->error( "Capture failed. {$error->getMessage()} {$error->getFile()}:{$error->getLine()}" );
|
||||
}
|
||||
|
||||
$wc_order->update_status(
|
||||
'failed',
|
||||
__( 'Could not capture the payment.', 'woocommerce-paypal-payments' )
|
||||
);
|
||||
},
|
||||
10,
|
||||
3
|
||||
);
|
||||
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_uninstall',
|
||||
static function () use ( $c ) {
|
||||
$endpoint = $c->get( 'wcgateway.endpoint.oxxo' );
|
||||
$endpoint->handle_request();
|
||||
$listener = $c->get( 'wcgateway.settings.listener' );
|
||||
assert( $listener instanceof SettingsListener );
|
||||
|
||||
$listener->listen_for_uninstall();
|
||||
}
|
||||
);
|
||||
|
||||
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||
\WP_CLI::add_command(
|
||||
'pcp settings',
|
||||
$c->get( 'wcgateway.cli.settings.command' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -393,14 +511,29 @@ class WCGatewayModule implements ModuleInterface {
|
|||
'admin_init',
|
||||
static function () use ( $container ) {
|
||||
$listener = $container->get( 'wcgateway.settings.listener' );
|
||||
/**
|
||||
* The settings listener.
|
||||
*
|
||||
* @var SettingsListener $listener
|
||||
*/
|
||||
assert( $listener instanceof SettingsListener );
|
||||
|
||||
$listener->listen_for_merchant_id();
|
||||
$listener->listen_for_vaulting_enabled();
|
||||
$listener->listen_for_tracking_enabled();
|
||||
|
||||
try {
|
||||
$listener->listen_for_vaulting_enabled();
|
||||
} catch ( RuntimeException $exception ) {
|
||||
add_action(
|
||||
'admin_notices',
|
||||
function () use ( $exception ) {
|
||||
printf(
|
||||
'<div class="notice notice-error"><p>%1$s</p><p>%2$s</p></div>',
|
||||
esc_html__( 'Authentication with PayPal failed: ', 'woocommerce-paypal-payments' ) . esc_attr( $exception->getMessage() ),
|
||||
wp_kses_post(
|
||||
__(
|
||||
'Please verify your API Credentials and try again to connect your PayPal business account. Visit the <a href="https://docs.woocommerce.com/document/woocommerce-paypal-payments/" target="_blank">plugin documentation</a> for more information about the setup.',
|
||||
'woocommerce-paypal-payments'
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -415,7 +548,6 @@ class WCGatewayModule implements ModuleInterface {
|
|||
*/
|
||||
$field = $renderer->render_multiselect( $field, $key, $args, $value );
|
||||
$field = $renderer->render_password( $field, $key, $args, $value );
|
||||
$field = $renderer->render_text_input( $field, $key, $args, $value );
|
||||
$field = $renderer->render_heading( $field, $key, $args, $value );
|
||||
$field = $renderer->render_table( $field, $key, $args, $value );
|
||||
return $field;
|
||||
|
@ -519,7 +651,7 @@ class WCGatewayModule implements ModuleInterface {
|
|||
* @var OrderTablePaymentStatusColumn $payment_status_column
|
||||
*/
|
||||
$payment_status_column = $container->get( 'wcgateway.admin.orders-payment-status-column' );
|
||||
$payment_status_column->render( $column, intval( $wc_order_id ) );
|
||||
$payment_status_column->render( (string) $column, intval( $wc_order_id ) );
|
||||
},
|
||||
10,
|
||||
2
|
||||
|
|
|
@ -6,10 +6,12 @@ module.exports = {
|
|||
mode: isProduction ? 'production' : 'development',
|
||||
target: 'web',
|
||||
entry: {
|
||||
'common': path.resolve('./resources/js/common.js'),
|
||||
'gateway-settings': path.resolve('./resources/js/gateway-settings.js'),
|
||||
'fraudnet': path.resolve('./resources/js/fraudnet.js'),
|
||||
'oxxo': path.resolve('./resources/js/oxxo.js'),
|
||||
'gateway-settings-style': path.resolve('./resources/css/gateway-settings.scss'),
|
||||
'common-style': path.resolve('./resources/css/common.scss'),
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'assets/'),
|
||||
|
|
|
@ -1028,12 +1028,7 @@
|
|||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.50"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
||||
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
||||
|
||||
"@types/estree@^0.0.51":
|
||||
"@types/estree@*", "@types/estree@^0.0.51":
|
||||
version "0.0.51"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40"
|
||||
integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==
|
||||
|
@ -1201,12 +1196,7 @@ acorn-import-assertions@^1.7.6:
|
|||
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz#580e3ffcae6770eebeec76c3b9723201e9d01f78"
|
||||
integrity sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA==
|
||||
|
||||
acorn@^8.5.0:
|
||||
version "8.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
|
||||
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
|
||||
|
||||
acorn@^8.7.1:
|
||||
acorn@^8.5.0, acorn@^8.7.1:
|
||||
version "8.8.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
|
||||
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
|
||||
|
@ -1299,18 +1289,7 @@ braces@~3.0.2:
|
|||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
browserslist@^4.14.5:
|
||||
version "4.17.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.1.tgz#a98d104f54af441290b7d592626dd541fa642eb9"
|
||||
integrity sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001259"
|
||||
electron-to-chromium "^1.3.846"
|
||||
escalade "^3.1.1"
|
||||
nanocolors "^0.1.5"
|
||||
node-releases "^1.1.76"
|
||||
|
||||
browserslist@^4.20.2, browserslist@^4.21.3:
|
||||
browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.21.3:
|
||||
version "4.21.3"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a"
|
||||
integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==
|
||||
|
@ -1333,11 +1312,6 @@ call-bind@^1.0.0:
|
|||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
caniuse-lite@^1.0.30001259:
|
||||
version "1.0.30001261"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001261.tgz#96d89813c076ea061209a4e040d8dcf0c66a1d01"
|
||||
integrity sha512-vM8D9Uvp7bHIN0fZ2KQ4wnmYFpJo/Etb4Vwsuc+ka0tfGDHvOPrFm6S/7CCNLSOkAUjenT2HnUPESdOIL91FaA==
|
||||
|
||||
caniuse-lite@^1.0.30001370:
|
||||
version "1.0.30001393"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356"
|
||||
|
@ -1462,11 +1436,6 @@ define-properties@^1.1.3:
|
|||
dependencies:
|
||||
object-keys "^1.0.12"
|
||||
|
||||
electron-to-chromium@^1.3.846:
|
||||
version "1.3.853"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.853.tgz#f3ed1d31f092cb3a17af188bca6c6a3ec91c3e82"
|
||||
integrity sha512-W4U8n+U8I5/SUaFcqZgbKRmYZwcyEIQVBDf+j5QQK6xChjXnQD+wj248eGR9X4u+dDmDR//8vIfbu4PrdBBIoQ==
|
||||
|
||||
electron-to-chromium@^1.4.202:
|
||||
version "1.4.247"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.247.tgz#cc93859bc5fc521f611656e65ce17eae26a0fd3d"
|
||||
|
@ -1628,12 +1597,7 @@ globals@^11.1.0:
|
|||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.2.4:
|
||||
version "4.2.8"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
|
||||
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
|
||||
|
||||
graceful-fs@^4.2.9:
|
||||
graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
|
||||
version "4.2.10"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
@ -1760,17 +1724,10 @@ json-schema-traverse@^0.4.1:
|
|||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json5@^2.1.2:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
|
||||
integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
json5@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
|
||||
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||
json5@^2.1.2, json5@^2.2.1:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
|
||||
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
|
||||
|
||||
kind-of@^6.0.2:
|
||||
version "6.0.3"
|
||||
|
@ -1788,9 +1745,9 @@ loader-runner@^4.2.0:
|
|||
integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
|
||||
|
||||
loader-utils@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
|
||||
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c"
|
||||
integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==
|
||||
dependencies:
|
||||
big.js "^5.2.2"
|
||||
emojis-list "^3.0.0"
|
||||
|
@ -1832,31 +1789,16 @@ mime-types@^2.1.27:
|
|||
dependencies:
|
||||
mime-db "1.49.0"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.6"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
nanocolors@^0.1.5:
|
||||
version "0.1.12"
|
||||
resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6"
|
||||
integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==
|
||||
|
||||
neo-async@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
|
||||
node-releases@^1.1.76:
|
||||
version "1.1.76"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.76.tgz#df245b062b0cafbd5282ab6792f7dccc2d97f36e"
|
||||
integrity sha512-9/IECtNr8dXNmPWmFXepT0/7o5eolGesHUa3mtr0KlgnCvnZxwh2qensKL42JJY2vQKC3nIBXetFAqR+PW1CmA==
|
||||
|
||||
node-releases@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
|
||||
|
@ -2294,10 +2236,10 @@ webpack-sources@^3.2.3:
|
|||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
|
||||
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
|
||||
|
||||
webpack@^5.74:
|
||||
version "5.74.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980"
|
||||
integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==
|
||||
webpack@^5.76:
|
||||
version "5.76.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.76.0.tgz#f9fb9fb8c4a7dbdcd0d56a98e56b8a942ee2692c"
|
||||
integrity sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.3"
|
||||
"@types/estree" "^0.0.51"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue