mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-04 08:47:23 +08:00
Merge branch 'trunk' into PCP-3828_fix-missind-void-auth-button
This commit is contained in:
commit
1b1fa37e4d
64 changed files with 26745 additions and 27817 deletions
|
@ -10,18 +10,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,20 +11,20 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^6.0.0",
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
|
@ -57,7 +57,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ppc-button-ppcp-applepay {
|
||||
display: none;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,54 +1,90 @@
|
|||
import buttonModuleWatcher from '../../../ppcp-button/resources/js/modules/ButtonModuleWatcher';
|
||||
import ApplePayButton from './ApplepayButton';
|
||||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
||||
|
||||
class ApplePayManager {
|
||||
#namespace = '';
|
||||
#buttonConfig = null;
|
||||
#ppcpConfig = null;
|
||||
#applePayConfig = null;
|
||||
#contextHandler = null;
|
||||
#transactionInfo = null;
|
||||
#buttons = [];
|
||||
|
||||
constructor( namespace, buttonConfig, ppcpConfig ) {
|
||||
this.namespace = namespace;
|
||||
this.buttonConfig = buttonConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
this.ApplePayConfig = null;
|
||||
this.buttons = [];
|
||||
this.#namespace = namespace;
|
||||
this.#buttonConfig = buttonConfig;
|
||||
this.#ppcpConfig = ppcpConfig;
|
||||
|
||||
buttonModuleWatcher.watchContextBootstrap( ( bootstrap ) => {
|
||||
const button = new ApplePayButton(
|
||||
bootstrap.context,
|
||||
bootstrap.handler,
|
||||
buttonConfig,
|
||||
ppcpConfig
|
||||
);
|
||||
|
||||
this.buttons.push( button );
|
||||
|
||||
if ( this.ApplePayConfig ) {
|
||||
button.init( this.ApplePayConfig );
|
||||
}
|
||||
} );
|
||||
this.onContextBootstrap = this.onContextBootstrap.bind( this );
|
||||
buttonModuleWatcher.watchContextBootstrap( this.onContextBootstrap );
|
||||
}
|
||||
|
||||
init() {
|
||||
( async () => {
|
||||
await this.config();
|
||||
for ( const button of this.buttons ) {
|
||||
button.init( this.ApplePayConfig );
|
||||
}
|
||||
} )();
|
||||
async onContextBootstrap( bootstrap ) {
|
||||
this.#contextHandler = ContextHandlerFactory.create(
|
||||
bootstrap.context,
|
||||
this.#buttonConfig,
|
||||
this.#ppcpConfig,
|
||||
bootstrap.handler
|
||||
);
|
||||
|
||||
const button = ApplePayButton.createButton(
|
||||
bootstrap.context,
|
||||
bootstrap.handler,
|
||||
this.#buttonConfig,
|
||||
this.#ppcpConfig,
|
||||
this.#contextHandler
|
||||
);
|
||||
|
||||
this.#buttons.push( button );
|
||||
|
||||
// Ensure ApplePayConfig is loaded before proceeding.
|
||||
await this.init();
|
||||
|
||||
button.configure( this.#applePayConfig, this.#transactionInfo );
|
||||
button.init();
|
||||
}
|
||||
|
||||
reinit() {
|
||||
for ( const button of this.buttons ) {
|
||||
button.reinit();
|
||||
async init() {
|
||||
try {
|
||||
if ( ! this.#applePayConfig ) {
|
||||
this.#applePayConfig = await window[ this.#namespace ]
|
||||
.Applepay()
|
||||
.config();
|
||||
|
||||
if ( ! this.#applePayConfig ) {
|
||||
console.error( 'No ApplePayConfig received during init' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! this.#transactionInfo ) {
|
||||
this.#transactionInfo = await this.fetchTransactionInfo();
|
||||
|
||||
if ( ! this.#applePayConfig ) {
|
||||
console.error( 'No transactionInfo found during init' );
|
||||
}
|
||||
}
|
||||
} catch ( error ) {
|
||||
console.error( 'Error during initialization:', error );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Apple Pay configuration of the PayPal merchant.
|
||||
*/
|
||||
async config() {
|
||||
this.ApplePayConfig = await window[ this.namespace ]
|
||||
.Applepay()
|
||||
.config();
|
||||
async fetchTransactionInfo() {
|
||||
try {
|
||||
if ( ! this.#contextHandler ) {
|
||||
throw new Error( 'ContextHandler is not initialized' );
|
||||
}
|
||||
return await this.#contextHandler.transactionInfo();
|
||||
} catch ( error ) {
|
||||
console.error( 'Error fetching transaction info:', error );
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return this.ApplePayConfig;
|
||||
reinit() {
|
||||
for ( const button of this.#buttons ) {
|
||||
button.reinit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,15 @@
|
|||
import ApplePayButton from './ApplepayButton';
|
||||
import ApplepayButton from './Block/components/ApplePayButton';
|
||||
|
||||
class ApplePayManagerBlockEditor {
|
||||
constructor( namespace, buttonConfig, ppcpConfig ) {
|
||||
this.namespace = namespace;
|
||||
this.buttonConfig = buttonConfig;
|
||||
this.ppcpConfig = ppcpConfig;
|
||||
|
||||
/*
|
||||
* On the front-end, the init method is called when a new button context was detected
|
||||
* via `buttonModuleWatcher`. In the block editor, we do not need to wait for the
|
||||
* context, but can initialize the button in the next event loop.
|
||||
*/
|
||||
setTimeout( () => this.init() );
|
||||
}
|
||||
|
||||
async init() {
|
||||
try {
|
||||
this.applePayConfig = await window[ this.namespace ]
|
||||
.Applepay()
|
||||
.config();
|
||||
|
||||
const button = new ApplePayButton(
|
||||
this.ppcpConfig.context,
|
||||
null,
|
||||
this.buttonConfig,
|
||||
this.ppcpConfig
|
||||
);
|
||||
|
||||
button.init( this.applePayConfig );
|
||||
} catch ( error ) {
|
||||
console.error( 'Failed to initialize Apple Pay:', error );
|
||||
}
|
||||
}
|
||||
}
|
||||
const ApplePayManagerBlockEditor = ( {
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
} ) => (
|
||||
<ApplepayButton
|
||||
namespace={ namespace }
|
||||
buttonConfig={ buttonConfig }
|
||||
ppcpConfig={ ppcpConfig }
|
||||
/>
|
||||
);
|
||||
|
||||
export default ApplePayManagerBlockEditor;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import { useState, useEffect } from '@wordpress/element';
|
||||
import useApiToGenerateButton from '../hooks/useApiToGenerateButton';
|
||||
import usePayPalScript from '../hooks/usePayPalScript';
|
||||
import useApplepayScript from '../hooks/useApplepayScript';
|
||||
import useApplepayConfig from '../hooks/useApplepayConfig';
|
||||
|
||||
const ApplepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
||||
const [ buttonHtml, setButtonHtml ] = useState( '' );
|
||||
const [ buttonElement, setButtonElement ] = useState( null );
|
||||
const [ componentFrame, setComponentFrame ] = useState( null );
|
||||
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
|
||||
|
||||
const isApplepayLoaded = useApplepayScript(
|
||||
componentFrame,
|
||||
buttonConfig,
|
||||
isPayPalLoaded
|
||||
);
|
||||
|
||||
const applepayConfig = useApplepayConfig( namespace, isApplepayLoaded );
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! buttonElement ) {
|
||||
return;
|
||||
}
|
||||
|
||||
setComponentFrame( buttonElement.ownerDocument );
|
||||
}, [ buttonElement ] );
|
||||
|
||||
const applepayButton = useApiToGenerateButton(
|
||||
componentFrame,
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
applepayConfig
|
||||
);
|
||||
|
||||
useEffect( () => {
|
||||
if ( applepayButton ) {
|
||||
setButtonHtml( applepayButton.outerHTML );
|
||||
}
|
||||
}, [ applepayButton ] );
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ setButtonElement }
|
||||
dangerouslySetInnerHTML={ { __html: buttonHtml } }
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ApplepayButton;
|
|
@ -0,0 +1,37 @@
|
|||
import { useEffect, useState } from '@wordpress/element';
|
||||
import useButtonStyles from './useButtonStyles';
|
||||
|
||||
const useApiToGenerateButton = (
|
||||
componentDocument,
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig,
|
||||
applepayConfig
|
||||
) => {
|
||||
const [ applepayButton, setApplepayButton ] = useState( null );
|
||||
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! buttonConfig || ! applepayConfig ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const button = document.createElement( 'apple-pay-button' );
|
||||
button.setAttribute(
|
||||
'buttonstyle',
|
||||
buttonConfig.buttonColor || 'black'
|
||||
);
|
||||
button.setAttribute( 'type', buttonConfig.buttonType || 'pay' );
|
||||
button.setAttribute( 'locale', buttonConfig.buttonLocale || 'en' );
|
||||
|
||||
setApplepayButton( button );
|
||||
|
||||
return () => {
|
||||
setApplepayButton( null );
|
||||
};
|
||||
}, [ namespace, buttonConfig, ppcpConfig, applepayConfig, buttonStyles ] );
|
||||
|
||||
return applepayButton;
|
||||
};
|
||||
|
||||
export default useApiToGenerateButton;
|
|
@ -0,0 +1,26 @@
|
|||
import { useState, useEffect } from '@wordpress/element';
|
||||
|
||||
const useApplepayConfig = ( namespace, isApplepayLoaded ) => {
|
||||
const [ applePayConfig, setApplePayConfig ] = useState( null );
|
||||
|
||||
useEffect( () => {
|
||||
const fetchConfig = async () => {
|
||||
if ( ! isApplepayLoaded ) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const config = await window[ namespace ].Applepay().config();
|
||||
setApplePayConfig( config );
|
||||
} catch ( error ) {
|
||||
console.error( 'Failed to fetch Apple Pay config:', error );
|
||||
}
|
||||
};
|
||||
|
||||
fetchConfig();
|
||||
}, [ namespace, isApplepayLoaded ] );
|
||||
|
||||
return applePayConfig;
|
||||
};
|
||||
|
||||
export default useApplepayConfig;
|
|
@ -0,0 +1,65 @@
|
|||
import { useState, useEffect } from '@wordpress/element';
|
||||
import { loadCustomScript } from '@paypal/paypal-js';
|
||||
|
||||
const useApplepayScript = (
|
||||
componentDocument,
|
||||
buttonConfig,
|
||||
isPayPalLoaded
|
||||
) => {
|
||||
const [ isApplepayLoaded, setIsApplepayLoaded ] = useState( false );
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! componentDocument ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const injectScriptToFrame = ( scriptSrc ) => {
|
||||
if ( document === componentDocument ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.querySelector(
|
||||
`script[src^="${ scriptSrc }"]`
|
||||
);
|
||||
|
||||
if ( script ) {
|
||||
const newScript = componentDocument.createElement( 'script' );
|
||||
newScript.src = script.src;
|
||||
newScript.async = script.async;
|
||||
newScript.type = script.type;
|
||||
|
||||
componentDocument.head.appendChild( newScript );
|
||||
} else {
|
||||
console.error( 'Script not found in the document:', scriptSrc );
|
||||
}
|
||||
};
|
||||
|
||||
const loadApplepayScript = async () => {
|
||||
if ( ! isPayPalLoaded ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! buttonConfig || ! buttonConfig.sdk_url ) {
|
||||
console.error( 'Invalid buttonConfig or missing sdk_url' );
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await loadCustomScript( { url: buttonConfig.sdk_url } ).then(
|
||||
() => {
|
||||
injectScriptToFrame( buttonConfig.sdk_url );
|
||||
}
|
||||
);
|
||||
setIsApplepayLoaded( true );
|
||||
} catch ( error ) {
|
||||
console.error( 'Failed to load Applepay script:', error );
|
||||
}
|
||||
};
|
||||
|
||||
loadApplepayScript();
|
||||
}, [ componentDocument, buttonConfig, isPayPalLoaded ] );
|
||||
|
||||
return isApplepayLoaded;
|
||||
};
|
||||
|
||||
export default useApplepayScript;
|
|
@ -0,0 +1,19 @@
|
|||
import { useMemo } from '@wordpress/element';
|
||||
import { combineStyles } from '../../../../../ppcp-button/resources/js/modules/Helper/PaymentButtonHelpers';
|
||||
|
||||
const useButtonStyles = ( buttonConfig, ppcpConfig ) => {
|
||||
return useMemo( () => {
|
||||
const styles = combineStyles(
|
||||
ppcpConfig?.button || {},
|
||||
buttonConfig?.button || {}
|
||||
);
|
||||
|
||||
if ( styles.MiniCart && styles.MiniCart.type === 'buy' ) {
|
||||
styles.MiniCart.type = 'pay';
|
||||
}
|
||||
|
||||
return styles;
|
||||
}, [ buttonConfig, ppcpConfig ] );
|
||||
};
|
||||
|
||||
export default useButtonStyles;
|
|
@ -0,0 +1,25 @@
|
|||
import { useState, useEffect } from '@wordpress/element';
|
||||
import { loadPayPalScript } from '../../../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
|
||||
|
||||
const usePayPalScript = ( namespace, ppcpConfig ) => {
|
||||
const [ isPayPalLoaded, setIsPayPalLoaded ] = useState( false );
|
||||
|
||||
ppcpConfig.url_params.components += ',applepay';
|
||||
|
||||
useEffect( () => {
|
||||
const loadScript = async () => {
|
||||
try {
|
||||
await loadPayPalScript( namespace, ppcpConfig );
|
||||
setIsPayPalLoaded( true );
|
||||
} catch ( error ) {
|
||||
console.error( `Error loading PayPal script: ${ error }` );
|
||||
}
|
||||
};
|
||||
|
||||
loadScript();
|
||||
}, [ namespace, ppcpConfig ] );
|
||||
|
||||
return isPayPalLoaded;
|
||||
};
|
||||
|
||||
export default usePayPalScript;
|
|
@ -5,6 +5,11 @@ import PreviewButton from '../../../../ppcp-button/resources/js/modules/Preview/
|
|||
* A single Apple Pay preview button instance.
|
||||
*/
|
||||
export default class ApplePayPreviewButton extends PreviewButton {
|
||||
/**
|
||||
* @type {?PaymentButton}
|
||||
*/
|
||||
#button = null;
|
||||
|
||||
constructor( args ) {
|
||||
super( args );
|
||||
|
||||
|
@ -19,14 +24,18 @@ export default class ApplePayPreviewButton extends PreviewButton {
|
|||
}
|
||||
|
||||
createButton( buttonConfig ) {
|
||||
const button = new ApplepayButton(
|
||||
'preview',
|
||||
null,
|
||||
buttonConfig,
|
||||
this.ppcpConfig
|
||||
);
|
||||
if ( ! this.#button ) {
|
||||
this.#button = new ApplepayButton(
|
||||
'preview',
|
||||
null,
|
||||
buttonConfig,
|
||||
this.ppcpConfig
|
||||
);
|
||||
}
|
||||
|
||||
button.init( this.apiConfig );
|
||||
this.#button.configure( this.apiConfig, null );
|
||||
this.#button.applyButtonStyles( buttonConfig, this.ppcpConfig );
|
||||
this.#button.reinit();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useState } from '@wordpress/element';
|
||||
import { useEffect, useRef, useState } from '@wordpress/element';
|
||||
import { registerExpressPaymentMethod } from '@woocommerce/blocks-registry';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
|
||||
import { cartHasSubscriptionProducts } from '../../../ppcp-blocks/resources/js/Helper/Subscription';
|
||||
import { loadCustomScript } from '@paypal/paypal-js';
|
||||
|
@ -18,20 +19,16 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
|
|||
window.PayPalCommerceGateway = ppcpConfig;
|
||||
}
|
||||
|
||||
const ApplePayComponent = ( props ) => {
|
||||
const [ bootstrapped, setBootstrapped ] = useState( false );
|
||||
const ApplePayComponent = ( { isEditing } ) => {
|
||||
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
||||
const [ applePayLoaded, setApplePayLoaded ] = useState( false );
|
||||
|
||||
const bootstrap = function () {
|
||||
const ManagerClass = props.isEditing
|
||||
? ApplePayManagerBlockEditor
|
||||
: ApplePayManager;
|
||||
const manager = new ManagerClass( namespace, buttonConfig, ppcpConfig );
|
||||
manager.init();
|
||||
};
|
||||
const wrapperRef = useRef( null );
|
||||
|
||||
useEffect( () => {
|
||||
if ( isEditing ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load ApplePay SDK
|
||||
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
|
||||
setApplePayLoaded( true );
|
||||
|
@ -47,17 +44,35 @@ const ApplePayComponent = ( props ) => {
|
|||
.catch( ( error ) => {
|
||||
console.error( 'Failed to load PayPal script: ', error );
|
||||
} );
|
||||
}, [] );
|
||||
}, [ isEditing ] );
|
||||
|
||||
useEffect( () => {
|
||||
if ( ! bootstrapped && paypalLoaded && applePayLoaded ) {
|
||||
setBootstrapped( true );
|
||||
bootstrap();
|
||||
if ( isEditing || ! paypalLoaded || ! applePayLoaded ) {
|
||||
return;
|
||||
}
|
||||
}, [ paypalLoaded, applePayLoaded ] );
|
||||
|
||||
const ManagerClass = isEditing
|
||||
? ApplePayManagerBlockEditor
|
||||
: ApplePayManager;
|
||||
|
||||
buttonConfig.reactWrapper = wrapperRef.current;
|
||||
|
||||
new ManagerClass( namespace, buttonConfig, ppcpConfig );
|
||||
}, [ paypalLoaded, applePayLoaded, isEditing ] );
|
||||
|
||||
if ( isEditing ) {
|
||||
return (
|
||||
<ApplePayManagerBlockEditor
|
||||
namespace={ namespace }
|
||||
buttonConfig={ buttonConfig }
|
||||
ppcpConfig={ ppcpConfig }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ wrapperRef }
|
||||
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
|
||||
className="ppcp-button-apm ppcp-button-applepay"
|
||||
></div>
|
||||
|
@ -75,6 +90,11 @@ if (
|
|||
|
||||
registerExpressPaymentMethod( {
|
||||
name: buttonData.id,
|
||||
title: `PayPal - ${ buttonData.title }`,
|
||||
description: __(
|
||||
'Eligible users will see the PayPal button.',
|
||||
'woocommerce-paypal-payments'
|
||||
),
|
||||
label: <div dangerouslySetInnerHTML={ { __html: buttonData.title } } />,
|
||||
content: <ApplePayComponent isEditing={ false } />,
|
||||
edit: <ApplePayComponent isEditing={ true } />,
|
||||
|
|
|
@ -3,33 +3,49 @@ import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Help
|
|||
import ApplePayManager from './ApplepayManager';
|
||||
import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Helper/ButtonRefreshHelper';
|
||||
|
||||
( function ( { buttonConfig, ppcpConfig, jQuery } ) {
|
||||
( function ( { buttonConfig, ppcpConfig } ) {
|
||||
const namespace = 'ppcpPaypalApplepay';
|
||||
let manager;
|
||||
|
||||
const bootstrap = function () {
|
||||
manager = new ApplePayManager( namespace, buttonConfig, ppcpConfig );
|
||||
manager.init();
|
||||
};
|
||||
|
||||
setupButtonEvents( function () {
|
||||
if ( manager ) {
|
||||
manager.reinit();
|
||||
}
|
||||
} );
|
||||
|
||||
document.addEventListener( 'DOMContentLoaded', () => {
|
||||
if (
|
||||
typeof buttonConfig === 'undefined' ||
|
||||
typeof ppcpConfig === 'undefined'
|
||||
) {
|
||||
function bootstrapPayButton() {
|
||||
if ( ! buttonConfig || ! ppcpConfig ) {
|
||||
return;
|
||||
}
|
||||
const isMiniCart = ppcpConfig.mini_cart_buttons_enabled;
|
||||
const isButton = jQuery( '#' + buttonConfig.button.wrapper ).length > 0;
|
||||
|
||||
const manager = new ApplePayManager(
|
||||
namespace,
|
||||
buttonConfig,
|
||||
ppcpConfig
|
||||
);
|
||||
|
||||
setupButtonEvents( function () {
|
||||
manager.reinit();
|
||||
} );
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
bootstrapPayButton();
|
||||
// Other Apple Pay bootstrapping could happen here.
|
||||
}
|
||||
|
||||
document.addEventListener( 'DOMContentLoaded', () => {
|
||||
if ( ! buttonConfig || ! ppcpConfig ) {
|
||||
/*
|
||||
* No PayPal buttons present on this page, but maybe a bootstrap module needs to be
|
||||
* initialized. Skip loading the SDK or gateway configuration, and directly initialize
|
||||
* the module.
|
||||
*/
|
||||
bootstrap();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const usedInMiniCart = ppcpConfig.mini_cart_buttons_enabled;
|
||||
const pageHasButton =
|
||||
null !== document.getElementById( buttonConfig.button.wrapper );
|
||||
|
||||
// If button wrapper is not present then there is no need to load the scripts.
|
||||
// minicart loads later?
|
||||
if ( ! isMiniCart && ! isButton ) {
|
||||
if ( ! usedInMiniCart && ! pageHasButton ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -63,5 +79,4 @@ import { setupButtonEvents } from '../../../ppcp-button/resources/js/modules/Hel
|
|||
} )( {
|
||||
buttonConfig: window.wc_ppcp_applepay,
|
||||
ppcpConfig: window.PayPalCommerceGateway,
|
||||
jQuery: window.jQuery,
|
||||
} );
|
||||
|
|
|
@ -105,6 +105,11 @@ class ApplePayGateway extends WC_Payment_Gateway {
|
|||
) {
|
||||
$this->id = self::ID;
|
||||
|
||||
$this->supports = array(
|
||||
'refunds',
|
||||
'products',
|
||||
);
|
||||
|
||||
$this->method_title = __( 'Apple Pay (via PayPal) ', 'woocommerce-paypal-payments' );
|
||||
$this->method_description = __( 'Display Apple Pay as a standalone payment option instead of bundling it with PayPal.', 'woocommerce-paypal-payments' );
|
||||
|
||||
|
|
|
@ -1008,7 +1008,7 @@ class ApplePayButton implements ButtonInterface {
|
|||
*/
|
||||
protected function hide_gateway_until_eligible(): void {
|
||||
?>
|
||||
<style id="ppcp-hide-apple-pay">.wc_payment_method.payment_method_ppcp-applepay{display:none}</style>
|
||||
<style data-hide-gateway="ppcp-applepay">.wc_payment_method.payment_method_ppcp-applepay{display:none}</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,22 +12,22 @@
|
|||
"dependencies": {
|
||||
"@paypal/paypal-js": "^8.1.1",
|
||||
"@paypal/react-paypal-js": "^8.5.0",
|
||||
"core-js": "^3.25.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"core-js": "^3.39",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,20 +11,20 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^6.0.0",
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,23 +11,23 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/react-paypal-js": "^8.5.0",
|
||||
"core-js": "^3.25.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"core-js": "^3.39",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@wordpress/i18n": "^5.6.0",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@wordpress/i18n": "^5.11",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,20 +12,20 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^6.0.0",
|
||||
"core-js": "^3.25.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
"core-js": "^3.39",
|
||||
"deepmerge": "^4.3",
|
||||
"formdata-polyfill": "^4.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
|
@ -10,6 +10,8 @@ import {
|
|||
dispatchButtonEvent,
|
||||
observeButtonEvent,
|
||||
} from '../Helper/PaymentButtonHelpers';
|
||||
import { isVisible } from '../Helper/Hiding';
|
||||
import { isDisabled, setEnabled } from '../Helper/ButtonDisabler';
|
||||
|
||||
/**
|
||||
* Collection of all available styling options for this button.
|
||||
|
@ -184,6 +186,13 @@ export default class PaymentButton {
|
|||
*/
|
||||
#isVisible = true;
|
||||
|
||||
/**
|
||||
* Whether this button is enabled (can be clicked).
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
#isEnabled = true;
|
||||
|
||||
/**
|
||||
* The currently visible payment button.
|
||||
*
|
||||
|
@ -192,6 +201,13 @@ export default class PaymentButton {
|
|||
*/
|
||||
#button = null;
|
||||
|
||||
/**
|
||||
* List of checks to perform to verify the PaymentButton has is configured correctly.
|
||||
*
|
||||
* @type {{check, errorMessage, shouldPass}[]}
|
||||
*/
|
||||
#validationChecks = [];
|
||||
|
||||
/**
|
||||
* Factory method to create a new PaymentButton while limiting a single instance per context.
|
||||
*
|
||||
|
@ -305,6 +321,11 @@ export default class PaymentButton {
|
|||
);
|
||||
this.applyButtonStyles( this.#buttonConfig );
|
||||
|
||||
this.registerValidationRules(
|
||||
this.#assertIsInvalid.bind( this ),
|
||||
this.#assertIsValid.bind( this )
|
||||
);
|
||||
|
||||
apmButtonsInit( this.#ppcpConfig );
|
||||
this.initEventListeners();
|
||||
}
|
||||
|
@ -559,6 +580,29 @@ export default class PaymentButton {
|
|||
this.triggerRedraw();
|
||||
}
|
||||
|
||||
/**
|
||||
* The enabled/disabled state of the button (whether it can be clicked).
|
||||
*
|
||||
* @return {boolean} True indicates, that the button is enabled.
|
||||
*/
|
||||
get isEnabled() {
|
||||
return this.#isEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the enabled/disabled state of the button.
|
||||
*
|
||||
* @param {boolean} newState Whether the button is enabled.
|
||||
*/
|
||||
set isEnabled( newState ) {
|
||||
if ( this.#isEnabled === newState ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.#isEnabled = newState;
|
||||
this.triggerRedraw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTML element that wraps the current button
|
||||
*
|
||||
|
@ -569,6 +613,23 @@ export default class PaymentButton {
|
|||
return document.getElementById( this.wrapperId );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the standard PayPal smart button selector for the current context.
|
||||
*
|
||||
* @return {string | null} The selector, or null if not available.
|
||||
*/
|
||||
get ppcpButtonWrapperSelector() {
|
||||
if ( PaymentContext.Blocks.includes( this.context ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( this.context === PaymentContext.MiniCart ) {
|
||||
return this.ppcpConfig?.button?.mini_cart_wrapper;
|
||||
}
|
||||
|
||||
return this.ppcpConfig?.button?.wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the main button-wrapper is present in the current DOM.
|
||||
*
|
||||
|
@ -634,16 +695,75 @@ export default class PaymentButton {
|
|||
this.#logger.group( label );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a validation check that marks the configuration as invalid when passed.
|
||||
*
|
||||
* @param {Function} check - A function that returns a truthy value if the check passes.
|
||||
* @param {string} errorMessage - The error message to display if the check fails.
|
||||
*/
|
||||
#assertIsInvalid( check, errorMessage ) {
|
||||
this.#validationChecks.push( {
|
||||
check,
|
||||
errorMessage,
|
||||
shouldPass: false,
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a validation check that instantly marks the configuration as valid when passed.
|
||||
*
|
||||
* @param {Function} check - A function that returns a truthy value if the check passes.
|
||||
*/
|
||||
#assertIsValid( check ) {
|
||||
this.#validationChecks.push( { check, shouldPass: true } );
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a series of validation steps to ensure the payment button is configured correctly.
|
||||
*
|
||||
* Each validation step is executed in the order they are defined within this method.
|
||||
*
|
||||
* If a validation step using `invalidIf` returns true, the configuration is immediately considered
|
||||
* invalid, and an error message is logged. Conversely, if a validation step using `validIf`
|
||||
* returns true, the configuration is immediately considered valid.
|
||||
*
|
||||
* If no validation step returns true, the configuration is assumed to be valid by default.
|
||||
*
|
||||
* @param {(condition: () => boolean, errorMessage: string) => void} invalidIf - Registers a validation step that fails if the condition returns true.
|
||||
* @param {(condition: () => boolean) => void} validIf - Registers a validation step that passes if the condition returns true.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
registerValidationRules( invalidIf, validIf ) {}
|
||||
|
||||
/**
|
||||
* Determines if the current button instance has valid and complete configuration details.
|
||||
* Used during initialization to decide if the button can be initialized or should be skipped.
|
||||
*
|
||||
* Can be implemented by the derived class.
|
||||
* All required validation steps must be registered in the constructor of the derived class
|
||||
* using `this.addValidationFailure()` or `this.addValidationSuccess()`.
|
||||
*
|
||||
* @param {boolean} [silent=false] - Set to true to suppress console errors.
|
||||
* @return {boolean} True indicates the config is valid and initialization can continue.
|
||||
*/
|
||||
validateConfiguration( silent = false ) {
|
||||
for ( const step of this.#validationChecks ) {
|
||||
const result = step.check();
|
||||
|
||||
if ( step.shouldPass && result ) {
|
||||
// If a success check passes, mark as valid immediately.
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! step.shouldPass && result ) {
|
||||
// If a failure check passes, mark as invalid.
|
||||
if ( ! silent && step.errorMessage ) {
|
||||
this.error( step.errorMessage );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -697,7 +817,23 @@ export default class PaymentButton {
|
|||
}
|
||||
|
||||
/**
|
||||
* Attaches event listeners to show or hide the payment button when needed.
|
||||
* Applies the visibility and enabled state from the PayPal button.
|
||||
* Intended for the product page, may not work correctly on the checkout page.
|
||||
*/
|
||||
syncProductButtonsState() {
|
||||
const ppcpButton = document.querySelector(
|
||||
this.ppcpButtonWrapperSelector
|
||||
);
|
||||
if ( ! ppcpButton ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isVisible = isVisible( ppcpButton );
|
||||
this.isEnabled = ! isDisabled( ppcpButton );
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches event listeners to show/hide or enable/disable the payment button when needed.
|
||||
*/
|
||||
initEventListeners() {
|
||||
// Refresh the button - this might show, hide or re-create the payment button.
|
||||
|
@ -726,6 +862,24 @@ export default class PaymentButton {
|
|||
callback: () => ( this.isVisible = true ),
|
||||
} );
|
||||
}
|
||||
|
||||
// On the product page, copy the visibility and enabled state from the PayPal button.
|
||||
if ( this.context === PaymentContext.Product ) {
|
||||
jQuery( document ).on(
|
||||
'ppcp-shown ppcp-hidden ppcp-enabled ppcp-disabled',
|
||||
( ev, data ) => {
|
||||
if (
|
||||
! jQuery( data.selector ).is(
|
||||
this.ppcpButtonWrapperSelector
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.syncProductButtonsState();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -812,6 +966,12 @@ export default class PaymentButton {
|
|||
|
||||
// Apply the wrapper visibility.
|
||||
wrapper.style.display = this.isVisible ? 'block' : 'none';
|
||||
|
||||
// Apply the enabled/disabled state.
|
||||
// On the product page, use the form to display error messages if clicked while disabled.
|
||||
const form =
|
||||
this.context === PaymentContext.Product ? 'form.cart' : null;
|
||||
setEnabled( wrapper, this.isEnabled, form );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,18 +10,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,18 +11,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,21 +11,21 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^6.0.0",
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@wordpress/i18n": "^5.6.0",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@wordpress/i18n": "^5.11",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
|
@ -215,45 +215,31 @@ class GooglepayButton extends PaymentButton {
|
|||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
validateConfiguration( silent = false ) {
|
||||
const validEnvs = [ 'PRODUCTION', 'TEST' ];
|
||||
registerValidationRules( invalidIf, validIf ) {
|
||||
invalidIf(
|
||||
() =>
|
||||
! [ 'TEST', 'PRODUCTION' ].includes(
|
||||
this.buttonConfig.environment
|
||||
),
|
||||
`Invalid environment: ${ this.buttonConfig.environment }`
|
||||
);
|
||||
|
||||
const isInvalid = ( ...args ) => {
|
||||
if ( ! silent ) {
|
||||
this.error( ...args );
|
||||
}
|
||||
return false;
|
||||
};
|
||||
validIf( () => this.isPreview );
|
||||
|
||||
if ( ! validEnvs.includes( this.buttonConfig.environment ) ) {
|
||||
return isInvalid(
|
||||
'Invalid environment:',
|
||||
this.buttonConfig.environment
|
||||
);
|
||||
}
|
||||
invalidIf(
|
||||
() => ! this.googlePayConfig,
|
||||
'No API configuration - missing configure() call?'
|
||||
);
|
||||
|
||||
// Preview buttons only need a valid environment.
|
||||
if ( this.isPreview ) {
|
||||
return true;
|
||||
}
|
||||
invalidIf(
|
||||
() => ! this.transactionInfo,
|
||||
'No transactionInfo - missing configure() call?'
|
||||
);
|
||||
|
||||
if ( ! this.googlePayConfig ) {
|
||||
return isInvalid(
|
||||
'No API configuration - missing configure() call?'
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! this.transactionInfo ) {
|
||||
return isInvalid(
|
||||
'No transactionInfo - missing configure() call?'
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! typeof this.contextHandler?.validateContext() ) {
|
||||
return isInvalid( 'Invalid context handler.', this.contextHandler );
|
||||
}
|
||||
|
||||
return true;
|
||||
invalidIf(
|
||||
() => ! this.contextHandler?.validateContext(),
|
||||
`Invalid context handler.`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,20 +10,20 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,18 +11,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
|
@ -9,6 +9,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\Onboarding;
|
||||
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\ConnectBearer;
|
||||
|
@ -19,7 +20,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
|
|||
use WooCommerce\PayPalCommerce\Onboarding\Assets\OnboardingAssets;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Endpoint\LoginSellerEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Endpoint\UpdateSignupLinksEndpoint;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingSendOnlyNoticeRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\OnboardingRESTController;
|
||||
|
||||
|
@ -239,6 +240,11 @@ return array(
|
|||
'sandbox-express_checkout',
|
||||
);
|
||||
},
|
||||
'onboarding.render-send-only-notice' => static function( ContainerInterface $container ) {
|
||||
return new OnboardingSendOnlyNoticeRenderer(
|
||||
$container->get( 'wcgateway.send-only-message' )
|
||||
);
|
||||
},
|
||||
'onboarding.render' => static function ( ContainerInterface $container ) : OnboardingRenderer {
|
||||
$partner_referrals = $container->get( 'api.endpoint.partner-referrals-production' );
|
||||
$partner_referrals_sandbox = $container->get( 'api.endpoint.partner-referrals-sandbox' );
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
/**
|
||||
* Creates an admin message that notifies user about send only country while onboarding.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\Onboarding\Render
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\Onboarding\Render;
|
||||
|
||||
/**
|
||||
* Class OnboardingRenderer
|
||||
*/
|
||||
class OnboardingSendOnlyNoticeRenderer {
|
||||
|
||||
/**
|
||||
* The notice message.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $message;
|
||||
|
||||
/**
|
||||
* AdminNotice constructor.
|
||||
*
|
||||
* @param string $message The notice message.
|
||||
*/
|
||||
public function __construct( string $message ) {
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the notice.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render(): string {
|
||||
return '<div class="notice notice-warning ppcp-notice-wrapper inline"><p>' . $this->message . '</p></div>';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -11,18 +11,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,22 +11,22 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/react-paypal-js": "^8.2.0",
|
||||
"core-js": "^3.25.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"core-js": "^3.39",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,20 +10,20 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,22 +11,22 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/react-paypal-js": "^8.2.0",
|
||||
"core-js": "^3.25.0",
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
"core-js": "^3.39",
|
||||
"react": "^18",
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,18 +10,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -10,21 +10,21 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0",
|
||||
"core-js": "^3.39",
|
||||
"@paypal/paypal-js": "^6.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"@babel/preset-react": "^7.18.6",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "^2.2.0",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"@babel/preset-react": "^7.25",
|
||||
"@woocommerce/dependency-extraction-webpack-plugin": "2.2.0",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -50,16 +50,53 @@ return array(
|
|||
return new ConnectManualRestEndpoint();
|
||||
},
|
||||
'settings.casual-selling.supported-countries' => static function ( ContainerInterface $container ) : array {
|
||||
// TODO: This is a dummy list, while we wait for the official eligibility list.
|
||||
|
||||
return array(
|
||||
'US',
|
||||
'CA',
|
||||
'DE',
|
||||
'ES',
|
||||
'AR',
|
||||
'AU',
|
||||
'AT',
|
||||
'CH',
|
||||
'BE',
|
||||
'BR',
|
||||
'CA',
|
||||
'CL',
|
||||
'CN',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DK',
|
||||
'EE',
|
||||
'FI',
|
||||
'FR',
|
||||
'GR',
|
||||
'HU',
|
||||
'ID',
|
||||
'IE',
|
||||
'IT',
|
||||
'JP',
|
||||
'LV',
|
||||
'LI',
|
||||
'LU',
|
||||
'MY',
|
||||
'MT',
|
||||
'NL',
|
||||
'NZ',
|
||||
'NO',
|
||||
'PH',
|
||||
'PL',
|
||||
'PT',
|
||||
'RO',
|
||||
'RU',
|
||||
'SM',
|
||||
'SA',
|
||||
'SG',
|
||||
'SK',
|
||||
'SI',
|
||||
'ZA',
|
||||
'KR',
|
||||
'ES',
|
||||
'SE',
|
||||
'TW',
|
||||
'GB',
|
||||
'US',
|
||||
'VN',
|
||||
);
|
||||
},
|
||||
'settings.casual-selling.eligible' => static function ( ContainerInterface $container ) : bool {
|
||||
|
|
|
@ -11,18 +11,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -12,18 +12,18 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@paypal/paypal-js": "^5.1.1",
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
|
@ -31,6 +31,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\VoidOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\CartCheckoutDetector;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\FeesUpdater;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\SendOnlyCountryNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\WcTasks\Factory\SimpleRedirectTaskFactory;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\WcTasks\Factory\SimpleRedirectTaskFactoryInterface;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Settings\WcTasks\Registrar\TaskRegistrar;
|
||||
|
@ -376,6 +377,113 @@ return array(
|
|||
$container->get( 'wcgateway.settings.status' )
|
||||
);
|
||||
},
|
||||
'wcgateway.store-country' => static function(): string {
|
||||
$location = wc_get_base_location();
|
||||
return $location['country'];
|
||||
},
|
||||
'wcgateway.send-only-message' => static function() {
|
||||
return __( "<strong>Important</strong>: Your current WooCommerce store location is in a \"send-only\" country, according to PayPal's policies. Sellers in these countries are unable to receive payments via PayPal. Since receiving payments is essential for using the PayPal Payments extension, you will not be able to connect your PayPal account while operating from a \"send-only\" country. To activate PayPal, please update your WooCommerce store location to a supported region and connect a PayPal account eligible for receiving payments.", 'woocommerce-paypal-payments' );
|
||||
},
|
||||
'wcgateway.send-only-countries' => static function() {
|
||||
return array(
|
||||
'AO',
|
||||
'AI',
|
||||
'AM',
|
||||
'AW',
|
||||
'AZ',
|
||||
'BY',
|
||||
'BJ',
|
||||
'BT',
|
||||
'BO',
|
||||
'VG',
|
||||
'BN',
|
||||
'BF',
|
||||
'BI',
|
||||
'CI',
|
||||
'KH',
|
||||
'CM',
|
||||
'CV',
|
||||
'TD',
|
||||
'KM',
|
||||
'CG',
|
||||
'CK',
|
||||
'DJ',
|
||||
'ER',
|
||||
'ET',
|
||||
'FK',
|
||||
'GA',
|
||||
'GM',
|
||||
'GN',
|
||||
'GW',
|
||||
'GY',
|
||||
'KI',
|
||||
'KG',
|
||||
'LA',
|
||||
'MK',
|
||||
'MG',
|
||||
'MV',
|
||||
'ML',
|
||||
'MH',
|
||||
'MR',
|
||||
'YT',
|
||||
'FM',
|
||||
'MN',
|
||||
'ME',
|
||||
'MS',
|
||||
'NA',
|
||||
'NR',
|
||||
'NP',
|
||||
'NE',
|
||||
'NG',
|
||||
'NU',
|
||||
'NF',
|
||||
'PG',
|
||||
'PY',
|
||||
'PN',
|
||||
'RW',
|
||||
'ST',
|
||||
'WS',
|
||||
'SL',
|
||||
'SB',
|
||||
'SO',
|
||||
'SH',
|
||||
'PM',
|
||||
'VC',
|
||||
'SR',
|
||||
'SJ',
|
||||
'TJ',
|
||||
'TZ',
|
||||
'TG',
|
||||
'TO',
|
||||
'TN',
|
||||
'TM',
|
||||
'TV',
|
||||
'UG',
|
||||
'UA',
|
||||
'VA',
|
||||
'WF',
|
||||
'YE',
|
||||
'ZM',
|
||||
'ZW',
|
||||
);
|
||||
},
|
||||
'wcgateway.is-send-only-country' => static function( ContainerInterface $container ) {
|
||||
$store_country = $container->get( 'wcgateway.store-country' );
|
||||
$send_only_countries = $container->get( 'wcgateway.send-only-countries' );
|
||||
return in_array( $store_country, $send_only_countries, true );
|
||||
},
|
||||
'wcgateway.notice.send-only-country' => static function ( ContainerInterface $container ) {
|
||||
$onboarding_state = $container->get( 'onboarding.state' );
|
||||
assert( $onboarding_state instanceof State );
|
||||
return new SendOnlyCountryNotice(
|
||||
$container->get( 'wcgateway.send-only-message' ),
|
||||
$container->get( 'wcgateway.is-send-only-country' ),
|
||||
$container->get( 'wcgateway.is-ppcp-settings-page' ),
|
||||
$container->get( 'wcgateway.is-wc-gateways-list-page' ),
|
||||
$onboarding_state->current_state()
|
||||
);
|
||||
},
|
||||
|
||||
'wcgateway.notice.authorize-order-action' =>
|
||||
static function ( ContainerInterface $container ): AuthorizeOrderActionNotice {
|
||||
return new AuthorizeOrderActionNotice();
|
||||
|
|
107
modules/ppcp-wc-gateway/src/Notice/SendOnlyCountryNotice.php
Normal file
107
modules/ppcp-wc-gateway/src/Notice/SendOnlyCountryNotice.php
Normal file
|
@ -0,0 +1,107 @@
|
|||
<?php
|
||||
/**
|
||||
* Creates an admin message that notifies user about send only country.
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* Creates an admin message that notifies user about send only country.
|
||||
*/
|
||||
class SendOnlyCountryNotice {
|
||||
|
||||
/**
|
||||
* Notice text
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected string $message_text;
|
||||
|
||||
/**
|
||||
* Indicates if current country is on the send only list
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $is_send_only_country;
|
||||
/**
|
||||
* Indicates if we're on the WooCommerce gateways list page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private bool $is_wc_gateways_list_page;
|
||||
|
||||
/**
|
||||
* Indicates if we're on a PPCP Settings page.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private bool $is_ppcp_settings_page;
|
||||
|
||||
/**
|
||||
* Onboarding state
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private int $onboarding_state;
|
||||
|
||||
/**
|
||||
* AdminNotice constructor.
|
||||
*
|
||||
* @param string $message_text The message text.
|
||||
* @param bool $is_send_only_country Determines if current WC country is a send only country.
|
||||
* @param bool $is_ppcp_settings_page Determines if current page is ppcp settings page.
|
||||
* @param bool $is_wc_gateways_list_page Determines if current page is ppcp gateway list page.
|
||||
* @param int $onboarding_state Determines current onboarding state.
|
||||
*/
|
||||
public function __construct(
|
||||
string $message_text,
|
||||
bool $is_send_only_country,
|
||||
bool $is_ppcp_settings_page,
|
||||
bool $is_wc_gateways_list_page,
|
||||
int $onboarding_state
|
||||
) {
|
||||
$this->message_text = $message_text;
|
||||
$this->is_send_only_country = $is_send_only_country;
|
||||
$this->is_ppcp_settings_page = $is_ppcp_settings_page;
|
||||
$this->is_wc_gateways_list_page = $is_wc_gateways_list_page;
|
||||
$this->onboarding_state = $onboarding_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message.
|
||||
*
|
||||
* @return Message|null
|
||||
*/
|
||||
public function message(): ?Message {
|
||||
|
||||
if ( ! $this->is_send_only_country ||
|
||||
! $this->is_ppcp_page() ||
|
||||
$this->onboarding_state === State::STATE_START
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Message(
|
||||
$this->message_text,
|
||||
'warning',
|
||||
true,
|
||||
'ppcp-notice-wrapper'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current page is ppcp page
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_ppcp_page():bool {
|
||||
return $this->is_ppcp_settings_page || $this->is_wc_gateways_list_page;
|
||||
}
|
||||
}
|
|
@ -12,10 +12,11 @@ declare(strict_types=1);
|
|||
namespace WooCommerce\PayPalCommerce\WcGateway\Settings;
|
||||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Render\OnboardingOptionsRenderer;
|
||||
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\Render\OnboardingSendOnlyNoticeRenderer;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Helper\DisplayManager;
|
||||
|
||||
|
@ -43,6 +44,13 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
$display_manager = $container->get( 'wcgateway.display-manager' );
|
||||
assert( $display_manager instanceof DisplayManager );
|
||||
|
||||
$onboarding_send_only_notice_renderer = $container->get( 'onboarding.render-send-only-notice' );
|
||||
assert( $onboarding_send_only_notice_renderer instanceof OnboardingSendOnlyNoticeRenderer );
|
||||
|
||||
$is_send_only_country = $container->get( 'wcgateway.is-send-only-country' );
|
||||
$onboarding_elements_class = $is_send_only_country ? 'hide' : 'ppcp-onboarding-element';
|
||||
$send_only_country_notice_class = $is_send_only_country ? 'ppcp-onboarding-element' : 'hide';
|
||||
|
||||
$connection_fields = array(
|
||||
'ppcp_onboarading_header' => array(
|
||||
'type' => 'ppcp-text',
|
||||
|
@ -101,10 +109,21 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
'description' => __( 'Your account is connected to sandbox, no real charging takes place. To accept live payments, turn off sandbox mode and connect your live PayPal account.', 'woocommerce-paypal-payments' ),
|
||||
),
|
||||
|
||||
'ppcp_send_only_countries_notice' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'classes' => array( $send_only_country_notice_class ),
|
||||
'text' => $onboarding_send_only_notice_renderer->render(),
|
||||
'raw' => true,
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
),
|
||||
'requirements' => array(),
|
||||
'gateway' => Settings::CONNECTION_TAB_ID,
|
||||
),
|
||||
'ppcp_onboarading_options' => array(
|
||||
'type' => 'ppcp-text',
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'text' => $onboarding_options_renderer->render(
|
||||
$is_shop_supports_dcc,
|
||||
$container->get( 'api.shop.country' ) === 'CN'
|
||||
|
@ -123,7 +142,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
// is to have the buttons before loading the script.
|
||||
'ppcp_onboarding_production_ppcp' => array(
|
||||
'type' => 'ppcp_onboarding',
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
),
|
||||
|
@ -135,7 +154,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'ppcp_onboarding_production_express' => array(
|
||||
'type' => 'ppcp_onboarding',
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
),
|
||||
|
@ -147,7 +166,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'ppcp_onboarding_sandbox_ppcp' => array(
|
||||
'type' => 'ppcp_onboarding',
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
),
|
||||
|
@ -160,7 +179,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
),
|
||||
'ppcp_onboarding_sandbox_express' => array(
|
||||
'type' => 'ppcp_onboarding',
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
),
|
||||
|
@ -214,7 +233,7 @@ return function ( ContainerInterface $container, array $fields ): array {
|
|||
esc_html__( 'Further information on manual credential input:', 'woocommerce-paypal-payments' ),
|
||||
esc_html__( 'documentation', 'woocommerce-paypal-payments' )
|
||||
),
|
||||
'classes' => array( 'ppcp-onboarding-element' ),
|
||||
'classes' => array( $onboarding_elements_class ),
|
||||
'screens' => array(
|
||||
State::STATE_START,
|
||||
State::STATE_ONBOARDED,
|
||||
|
|
|
@ -24,6 +24,7 @@ use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
|
|||
use WooCommerce\PayPalCommerce\WcGateway\Assets\VoidButtonAssets;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\RefreshFeatureStatusEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\VoidOrderEndpoint;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Notice\SendOnlyCountryNotice;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Processor\CreditCardOrderInfoHandlingTrait;
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\AdminNotices\Repository\Repository;
|
||||
|
@ -237,6 +238,13 @@ class WCGatewayModule implements ServiceModule, ExtendingModule, ExecutableModul
|
|||
}
|
||||
}
|
||||
|
||||
$send_only_country_notice = $c->get( 'wcgateway.notice.send-only-country' );
|
||||
assert( $send_only_country_notice instanceof SendOnlyCountryNotice );
|
||||
$message = $send_only_country_notice->message();
|
||||
if ( $message ) {
|
||||
$notices[] = $message;
|
||||
}
|
||||
|
||||
$authorize_order_action = $c->get( 'wcgateway.notice.authorize-order-action' );
|
||||
$authorized_message = $authorize_order_action->message();
|
||||
if ( $authorized_message ) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -11,18 +11,18 @@
|
|||
"Edge >= 14"
|
||||
],
|
||||
"dependencies": {
|
||||
"core-js": "^3.25.0"
|
||||
"core-js": "^3.39"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19",
|
||||
"@babel/preset-env": "^7.19",
|
||||
"babel-loader": "^8.2",
|
||||
"@babel/core": "^7.26",
|
||||
"@babel/preset-env": "^7.26",
|
||||
"babel-loader": "^9.2",
|
||||
"cross-env": "^7.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"sass": "^1.42.1",
|
||||
"sass-loader": "^12.1.0",
|
||||
"webpack": "^5.76",
|
||||
"webpack-cli": "^4.10"
|
||||
"sass": "^1.80",
|
||||
"sass-loader": "^16",
|
||||
"webpack": "^5.96",
|
||||
"webpack-cli": "^5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env BABEL_ENV=default NODE_ENV=production webpack",
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue