2024-12-03 16:06:18 +01:00
|
|
|
import { __ } from '@wordpress/i18n';
|
|
|
|
import { useDispatch } from '@wordpress/data';
|
|
|
|
import { store as noticesStore } from '@wordpress/notices';
|
|
|
|
|
|
|
|
import { CommonHooks, OnboardingHooks } from '../data';
|
|
|
|
import { openPopup } from '../utils/window';
|
|
|
|
|
2024-12-05 14:52:10 +01:00
|
|
|
const MESSAGES = {
|
|
|
|
CONNECTED: __( 'Connected to PayPal', 'woocommerce-paypal-payments' ),
|
|
|
|
POPUP_BLOCKED: __(
|
|
|
|
'Popup blocked. Please allow popups for this site to connect to PayPal.',
|
|
|
|
'woocommerce-paypal-payments'
|
|
|
|
),
|
|
|
|
SANDBOX_ERROR: __(
|
|
|
|
'Could not generate a Sandbox login link.',
|
|
|
|
'woocommerce-paypal-payments'
|
|
|
|
),
|
|
|
|
PRODUCTION_ERROR: __(
|
|
|
|
'Could not generate a login link.',
|
|
|
|
'woocommerce-paypal-payments'
|
|
|
|
),
|
|
|
|
MANUAL_ERROR: __(
|
|
|
|
'Could not connect to PayPal. Please make sure your Client ID and Secret Key are correct.',
|
|
|
|
'woocommerce-paypal-payments'
|
|
|
|
),
|
|
|
|
};
|
|
|
|
|
2024-12-05 16:09:28 +01:00
|
|
|
const handlePopupWithCompletion = ( url, onError ) => {
|
|
|
|
return new Promise( ( resolve ) => {
|
|
|
|
const popup = openPopup( url );
|
|
|
|
|
|
|
|
if ( ! popup ) {
|
|
|
|
onError( MESSAGES.POPUP_BLOCKED );
|
|
|
|
resolve( false );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check popup state every 500ms
|
|
|
|
const checkPopup = setInterval( () => {
|
|
|
|
if ( popup.closed ) {
|
|
|
|
clearInterval( checkPopup );
|
|
|
|
resolve( true );
|
|
|
|
}
|
|
|
|
}, 500 );
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
clearInterval( checkPopup );
|
|
|
|
|
|
|
|
if ( popup && ! popup.closed ) {
|
|
|
|
popup.close();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} );
|
2024-12-05 15:03:03 +01:00
|
|
|
};
|
|
|
|
|
2024-12-05 15:02:02 +01:00
|
|
|
const useConnectionBase = () => {
|
2024-12-03 16:06:18 +01:00
|
|
|
const { setCompleted } = OnboardingHooks.useSteps();
|
|
|
|
const { createSuccessNotice, createErrorNotice } =
|
|
|
|
useDispatch( noticesStore );
|
|
|
|
|
2024-12-05 15:02:02 +01:00
|
|
|
return {
|
|
|
|
handleError: ( res, genericMessage ) => {
|
|
|
|
console.error( 'Connection error', res );
|
|
|
|
createErrorNotice( res?.message ?? genericMessage );
|
|
|
|
},
|
|
|
|
handleSuccess: async () => {
|
|
|
|
createSuccessNotice( MESSAGES.CONNECTED );
|
2024-12-05 16:09:28 +01:00
|
|
|
|
|
|
|
// TODO: Contact the plugin to confirm onboarding is completed.
|
2024-12-05 15:02:02 +01:00
|
|
|
return setCompleted( true );
|
|
|
|
},
|
|
|
|
createErrorNotice,
|
2024-12-03 16:06:18 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-12-05 15:04:36 +01:00
|
|
|
const useConnectionAttempt = ( connectFn, errorMessage ) => {
|
2024-12-05 16:09:28 +01:00
|
|
|
const { handleError, createErrorNotice, handleSuccess } =
|
|
|
|
useConnectionBase();
|
2024-12-05 15:04:36 +01:00
|
|
|
|
|
|
|
return async ( ...args ) => {
|
|
|
|
const res = await connectFn( ...args );
|
|
|
|
|
|
|
|
if ( ! res.success || ! res.data ) {
|
|
|
|
handleError( res, errorMessage );
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-12-05 16:09:28 +01:00
|
|
|
const popupClosed = await handlePopupWithCompletion(
|
|
|
|
res.data,
|
|
|
|
createErrorNotice
|
|
|
|
);
|
|
|
|
|
|
|
|
if ( popupClosed ) {
|
|
|
|
await handleSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
return popupClosed;
|
2024-12-05 15:04:36 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-12-03 16:06:18 +01:00
|
|
|
export const useSandboxConnection = () => {
|
2024-12-03 17:54:09 +01:00
|
|
|
const { connectToSandbox, isSandboxMode, setSandboxMode } =
|
2024-12-03 16:06:18 +01:00
|
|
|
CommonHooks.useSandbox();
|
2024-12-05 15:03:03 +01:00
|
|
|
const handleSandboxConnect = useConnectionAttempt(
|
|
|
|
connectToSandbox,
|
|
|
|
MESSAGES.SANDBOX_ERROR
|
|
|
|
);
|
2024-12-03 16:06:18 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
handleSandboxConnect,
|
|
|
|
isSandboxMode,
|
|
|
|
setSandboxMode,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-12-05 15:05:00 +01:00
|
|
|
export const useProductionConnection = () => {
|
|
|
|
const { connectToProduction } = CommonHooks.useProduction();
|
|
|
|
const products = OnboardingHooks.useDetermineProducts();
|
|
|
|
const handleProductionConnect = useConnectionAttempt(
|
|
|
|
() => connectToProduction( products ),
|
|
|
|
MESSAGES.PRODUCTION_ERROR
|
|
|
|
);
|
|
|
|
|
|
|
|
return { handleProductionConnect };
|
|
|
|
};
|
|
|
|
|
2024-12-03 16:06:18 +01:00
|
|
|
export const useManualConnection = () => {
|
2024-12-05 15:04:36 +01:00
|
|
|
const { handleError, handleSuccess, createErrorNotice } =
|
|
|
|
useConnectionBase();
|
2024-12-03 16:06:18 +01:00
|
|
|
const {
|
|
|
|
connectViaIdAndSecret,
|
|
|
|
isManualConnectionMode,
|
|
|
|
setManualConnectionMode,
|
|
|
|
clientId,
|
|
|
|
setClientId,
|
|
|
|
clientSecret,
|
|
|
|
setClientSecret,
|
|
|
|
} = CommonHooks.useManualConnection();
|
|
|
|
|
|
|
|
const handleConnectViaIdAndSecret = async ( { validation } = {} ) => {
|
|
|
|
if ( 'function' === typeof validation ) {
|
|
|
|
try {
|
|
|
|
validation();
|
|
|
|
} catch ( exception ) {
|
|
|
|
createErrorNotice( exception.message );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2024-12-05 15:04:36 +01:00
|
|
|
|
2024-12-03 16:06:18 +01:00
|
|
|
const res = await connectViaIdAndSecret();
|
|
|
|
|
|
|
|
if ( res.success ) {
|
2024-12-05 15:02:02 +01:00
|
|
|
await handleSuccess();
|
2024-12-03 16:06:18 +01:00
|
|
|
} else {
|
2024-12-05 15:02:02 +01:00
|
|
|
handleError( res, MESSAGES.MANUAL_ERROR );
|
2024-12-03 16:06:18 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
handleConnectViaIdAndSecret,
|
|
|
|
isManualConnectionMode,
|
|
|
|
setManualConnectionMode,
|
|
|
|
clientId,
|
|
|
|
setClientId,
|
|
|
|
clientSecret,
|
|
|
|
setClientSecret,
|
|
|
|
};
|
|
|
|
};
|