mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-05 08:59:14 +08:00
🔀 Merge branch 'trunk'
This commit is contained in:
commit
32d870bd6b
39 changed files with 11104 additions and 307 deletions
|
@ -1,5 +1,30 @@
|
||||||
*** Changelog ***
|
*** Changelog ***
|
||||||
|
|
||||||
|
= 2.9.3 - 2024-10-15 =
|
||||||
|
* Fix - Multi-currency support #2667
|
||||||
|
* Fix - "0.00" amount in Google Pay for virtual products #2636
|
||||||
|
* Fix - Unsuccessfully payment from product page with Apple Pay button #2643
|
||||||
|
* Fix - Button Unlinking PayPal Subscriptions plan does not showing for simple subscription #2618
|
||||||
|
* Fix - Declare tokenization for ACDC only when vaulting enabled #2581
|
||||||
|
* Fix - Classic shortcode block type checks #2608
|
||||||
|
* Fix - PUI error in editor #2580
|
||||||
|
* Fix - Add a new namespaced script loader for ApplePay #2682 #2675
|
||||||
|
* Fix - Axo Block: Fix the Fastlane modal info message text overflow issue #2663
|
||||||
|
* Fix - Add Custom Placeholder Handling when rendering the card fields #2651
|
||||||
|
* Fix - Use the PayPal icons instead of WC ones #2639
|
||||||
|
* Fix - Google Pay preview config and style #2661
|
||||||
|
* Fix - Improve context detection #2631
|
||||||
|
* Fix - Check that get_the_ID is valid before using #2573
|
||||||
|
* Fix - Axo Block: Always display the Fastlane watermark in the includeAdditionalInfo mode #2690
|
||||||
|
* Fix - Axo Block: Display card fields for authenticated cardless profiles #2672
|
||||||
|
* Fix - Google Pay: Fix button preview in the editor #2688
|
||||||
|
* Fix - ACDC gateway not visible on the block Checkout for logged-out users #2693
|
||||||
|
* Enhancement - Enhancement - Add Fastlane support for Checkout block
|
||||||
|
* Enhancement - Multiple calls to POST /v1/oauth2/token?grant_type=client_credentials&response_type=id_token #2671
|
||||||
|
* Enhancement - Fastlane update shipping options & taxes when changing address #2665
|
||||||
|
* Enhancement - Axo: Remove Axo from the Checkout block in the editor and add an ACDC card preview #2662
|
||||||
|
* Enhancement - Set email when creating order for express payment #2577
|
||||||
|
|
||||||
= 2.9.2 - 2024-10-01 =
|
= 2.9.2 - 2024-10-01 =
|
||||||
* Enhancement - Add Fastlane support for Classic Checkout
|
* Enhancement - Add Fastlane support for Classic Checkout
|
||||||
* Fix - Fatal error when Pay Later messaging configurator was disabled with a code snippet
|
* Fix - Fatal error when Pay Later messaging configurator was disabled with a code snippet
|
||||||
|
|
|
@ -90,5 +90,12 @@ return function ( string $root_dir ): iterable {
|
||||||
$modules[] = ( require "$modules_dir/ppcp-axo-block/module.php" )();
|
$modules[] = ( require "$modules_dir/ppcp-axo-block/module.php" )();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( apply_filters(
|
||||||
|
'woocommerce.feature-flags.woocommerce_paypal_payments.settings_enabled',
|
||||||
|
getenv( 'PCP_SETTINGS_ENABLED' ) === '1'
|
||||||
|
) ) {
|
||||||
|
$modules[] = ( require "$modules_dir/ppcp-settings/module.php" )();
|
||||||
|
}
|
||||||
|
|
||||||
return $modules;
|
return $modules;
|
||||||
};
|
};
|
||||||
|
|
|
@ -716,7 +716,6 @@ return array(
|
||||||
'FR' => $mastercard_visa_amex,
|
'FR' => $mastercard_visa_amex,
|
||||||
'GB' => $mastercard_visa_amex,
|
'GB' => $mastercard_visa_amex,
|
||||||
'GR' => $mastercard_visa_amex,
|
'GR' => $mastercard_visa_amex,
|
||||||
'HK' => $mastercard_visa_amex,
|
|
||||||
'HU' => $mastercard_visa_amex,
|
'HU' => $mastercard_visa_amex,
|
||||||
'IE' => $mastercard_visa_amex,
|
'IE' => $mastercard_visa_amex,
|
||||||
'IT' => $mastercard_visa_amex,
|
'IT' => $mastercard_visa_amex,
|
||||||
|
@ -746,7 +745,6 @@ return array(
|
||||||
'SE' => $mastercard_visa_amex,
|
'SE' => $mastercard_visa_amex,
|
||||||
'SI' => $mastercard_visa_amex,
|
'SI' => $mastercard_visa_amex,
|
||||||
'SK' => $mastercard_visa_amex,
|
'SK' => $mastercard_visa_amex,
|
||||||
'SG' => $mastercard_visa_amex,
|
|
||||||
'JP' => array(
|
'JP' => array(
|
||||||
'mastercard' => array(),
|
'mastercard' => array(),
|
||||||
'visa' => array(),
|
'visa' => array(),
|
||||||
|
|
|
@ -191,7 +191,6 @@ return array(
|
||||||
'FR', // France
|
'FR', // France
|
||||||
'DE', // Germany
|
'DE', // Germany
|
||||||
'GR', // Greece
|
'GR', // Greece
|
||||||
'HK', // Hong Kong
|
|
||||||
'HU', // Hungary
|
'HU', // Hungary
|
||||||
'IE', // Ireland
|
'IE', // Ireland
|
||||||
'IT', // Italy
|
'IT', // Italy
|
||||||
|
@ -205,7 +204,6 @@ return array(
|
||||||
'PL', // Poland
|
'PL', // Poland
|
||||||
'PT', // Portugal
|
'PT', // Portugal
|
||||||
'RO', // Romania
|
'RO', // Romania
|
||||||
'SG', // Singapore
|
|
||||||
'SK', // Slovakia
|
'SK', // Slovakia
|
||||||
'SI', // Slovenia
|
'SI', // Slovenia
|
||||||
'ES', // Spain
|
'ES', // Spain
|
||||||
|
|
|
@ -174,9 +174,6 @@ $fast-transition-duration: 0.5s;
|
||||||
grid-area: watermark;
|
grid-area: watermark;
|
||||||
justify-self: end;
|
justify-self: end;
|
||||||
grid-column: 1;
|
grid-column: 1;
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.wc-block-axo-is-authenticated) .wc-block-checkout-axo-block-watermark-container {
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,8 +256,8 @@ a.wc-block-axo-change-link {
|
||||||
.wp-block-woocommerce-checkout-fields-block:not(.wc-block-axo-is-loaded) {
|
.wp-block-woocommerce-checkout-fields-block:not(.wc-block-axo-is-loaded) {
|
||||||
.wc-block-checkout-axo-block-watermark-container {
|
.wc-block-checkout-axo-block-watermark-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: left;
|
justify-content: right;
|
||||||
margin-left: 10px;
|
margin-right: 10px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useEffect, useCallback, useState } from '@wordpress/element';
|
import { useEffect, useCallback, useState } from '@wordpress/element';
|
||||||
import { useSelect } from '@wordpress/data';
|
import { useSelect } from '@wordpress/data';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { log } from '../../../../../ppcp-axo/resources/js/Helper/Debug';
|
||||||
import { Card } from '../Card';
|
import { Card } from '../Card';
|
||||||
import { STORE_NAME } from '../../stores/axoStore';
|
import { STORE_NAME } from '../../stores/axoStore';
|
||||||
|
|
||||||
|
@ -16,27 +17,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
|
||||||
const [ isCardElementReady, setIsCardElementReady ] = useState( false );
|
const [ isCardElementReady, setIsCardElementReady ] = useState( false );
|
||||||
|
|
||||||
// Select relevant states from the AXO store
|
// Select relevant states from the AXO store
|
||||||
const { isGuest, isEmailLookupCompleted } = useSelect(
|
const { isGuest, isEmailLookupCompleted, cardDetails } = useSelect(
|
||||||
( select ) => ( {
|
( select ) => ( {
|
||||||
isGuest: select( STORE_NAME ).getIsGuest(),
|
isGuest: select( STORE_NAME ).getIsGuest(),
|
||||||
isEmailLookupCompleted:
|
isEmailLookupCompleted:
|
||||||
select( STORE_NAME ).getIsEmailLookupCompleted(),
|
select( STORE_NAME ).getIsEmailLookupCompleted(),
|
||||||
|
cardDetails: select( STORE_NAME ).getCardDetails(),
|
||||||
} ),
|
} ),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and renders the Fastlane card fields component when necessary.
|
||||||
|
* This function is called for:
|
||||||
|
* 1. Guest users who have completed email lookup
|
||||||
|
* 2. Authenticated users who are missing card details
|
||||||
|
*
|
||||||
|
* The component allows users to enter new card details for payment.
|
||||||
|
*/
|
||||||
const loadPaymentComponent = useCallback( async () => {
|
const loadPaymentComponent = useCallback( async () => {
|
||||||
if ( isGuest && isEmailLookupCompleted && isCardElementReady ) {
|
if (
|
||||||
const paymentComponent = await fastlaneSdk.FastlaneCardComponent(
|
( isGuest && isEmailLookupCompleted && isCardElementReady ) ||
|
||||||
{}
|
( ! isGuest && ! cardDetails )
|
||||||
);
|
) {
|
||||||
paymentComponent.render( `#fastlane-card` );
|
try {
|
||||||
onPaymentLoad( paymentComponent );
|
const paymentComponent =
|
||||||
|
await fastlaneSdk.FastlaneCardComponent( {} );
|
||||||
|
// Check if the container exists before rendering
|
||||||
|
const cardContainer =
|
||||||
|
document.querySelector( '#fastlane-card' );
|
||||||
|
if ( cardContainer ) {
|
||||||
|
paymentComponent.render( '#fastlane-card' );
|
||||||
|
onPaymentLoad( paymentComponent );
|
||||||
|
}
|
||||||
|
} catch ( error ) {
|
||||||
|
log( `Error loading payment component: ${ error }`, 'error' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
isGuest,
|
isGuest,
|
||||||
isEmailLookupCompleted,
|
isEmailLookupCompleted,
|
||||||
isCardElementReady,
|
isCardElementReady,
|
||||||
|
cardDetails,
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
onPaymentLoad,
|
onPaymentLoad,
|
||||||
] );
|
] );
|
||||||
|
@ -48,27 +70,48 @@ export const Payment = ( { fastlaneSdk, onPaymentLoad } ) => {
|
||||||
}
|
}
|
||||||
}, [ isGuest, isEmailLookupCompleted ] );
|
}, [ isGuest, isEmailLookupCompleted ] );
|
||||||
|
|
||||||
// Load payment component when dependencies change
|
// Load payment component when card element is ready
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
loadPaymentComponent();
|
if ( isCardElementReady ) {
|
||||||
}, [ loadPaymentComponent ] );
|
loadPaymentComponent();
|
||||||
|
|
||||||
// Conditional rendering based on user state:
|
|
||||||
// 1. If authenticated: Render the Card component
|
|
||||||
// 2. If guest with completed email lookup: Render the card fields
|
|
||||||
// 3. If guest without completed email lookup: Render a message to enter email
|
|
||||||
if ( isGuest ) {
|
|
||||||
if ( isEmailLookupCompleted ) {
|
|
||||||
return <div id="fastlane-card" key="fastlane-card" />;
|
|
||||||
}
|
}
|
||||||
return (
|
}, [ isCardElementReady, loadPaymentComponent ] );
|
||||||
<div id="ppcp-axo-block-radio-content">
|
|
||||||
{ __(
|
/**
|
||||||
'Enter your email address above to continue.',
|
* Determines which component to render based on the current state.
|
||||||
'woocommerce-paypal-payments'
|
*
|
||||||
) }
|
* Rendering logic:
|
||||||
</div>
|
* 1. For guests without completed email lookup: Show message to enter email
|
||||||
);
|
* 2. For guests with completed email lookup: Render Fastlane card fields
|
||||||
}
|
* 3. For authenticated users without card details: Render Fastlane card fields
|
||||||
return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />;
|
* 4. For authenticated users with card details: Render Card component
|
||||||
|
*
|
||||||
|
* @return {JSX.Element} The appropriate component based on the current state
|
||||||
|
*/
|
||||||
|
const renderPaymentComponent = () => {
|
||||||
|
// Case 1: Guest user without completed email lookup
|
||||||
|
if ( isGuest && ! isEmailLookupCompleted ) {
|
||||||
|
return (
|
||||||
|
<div id="ppcp-axo-block-radio-content">
|
||||||
|
{ __(
|
||||||
|
'Enter your email address above to continue.',
|
||||||
|
'woocommerce-paypal-payments'
|
||||||
|
) }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2 & 3: Guest with completed email lookup or authenticated user without card details
|
||||||
|
if (
|
||||||
|
( isGuest && isEmailLookupCompleted ) ||
|
||||||
|
( ! isGuest && ! cardDetails )
|
||||||
|
) {
|
||||||
|
return <div id="fastlane-card" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 4: Authenticated user with card details
|
||||||
|
return <Card fastlaneSdk={ fastlaneSdk } showWatermark={ ! isGuest } />;
|
||||||
|
};
|
||||||
|
|
||||||
|
return renderPaymentComponent();
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,9 +16,6 @@ import {
|
||||||
*/
|
*/
|
||||||
const WatermarkManager = ( { fastlaneSdk } ) => {
|
const WatermarkManager = ( { fastlaneSdk } ) => {
|
||||||
// Select relevant states from the AXO store
|
// Select relevant states from the AXO store
|
||||||
const isGuest = useSelect( ( select ) =>
|
|
||||||
select( STORE_NAME ).getIsGuest()
|
|
||||||
);
|
|
||||||
const isAxoActive = useSelect( ( select ) =>
|
const isAxoActive = useSelect( ( select ) =>
|
||||||
select( STORE_NAME ).getIsAxoActive()
|
select( STORE_NAME ).getIsAxoActive()
|
||||||
);
|
);
|
||||||
|
@ -34,7 +31,6 @@ const WatermarkManager = ( { fastlaneSdk } ) => {
|
||||||
isAxoActive,
|
isAxoActive,
|
||||||
isAxoScriptLoaded,
|
isAxoScriptLoaded,
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
isGuest,
|
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
// Remove watermark when AXO is inactive and not loading
|
// Remove watermark when AXO is inactive and not loading
|
||||||
|
@ -43,7 +39,7 @@ const WatermarkManager = ( { fastlaneSdk } ) => {
|
||||||
|
|
||||||
// Cleanup function to remove watermark on unmount
|
// Cleanup function to remove watermark on unmount
|
||||||
return removeWatermark;
|
return removeWatermark;
|
||||||
}, [ fastlaneSdk, isGuest, isAxoActive, isAxoScriptLoaded ] );
|
}, [ fastlaneSdk, isAxoActive, isAxoScriptLoaded ] );
|
||||||
|
|
||||||
// This component doesn't render anything directly
|
// This component doesn't render anything directly
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -112,13 +112,11 @@ export const renderWatermarkContent = ( content ) => {
|
||||||
* @param {boolean} params.isAxoActive - Whether AXO is active.
|
* @param {boolean} params.isAxoActive - Whether AXO is active.
|
||||||
* @param {boolean} params.isAxoScriptLoaded - Whether AXO script is loaded.
|
* @param {boolean} params.isAxoScriptLoaded - Whether AXO script is loaded.
|
||||||
* @param {Object} params.fastlaneSdk - The Fastlane SDK instance.
|
* @param {Object} params.fastlaneSdk - The Fastlane SDK instance.
|
||||||
* @param {boolean} params.isGuest - Whether the user is a guest.
|
|
||||||
*/
|
*/
|
||||||
export const updateWatermarkContent = ( {
|
export const updateWatermarkContent = ( {
|
||||||
isAxoActive,
|
isAxoActive,
|
||||||
isAxoScriptLoaded,
|
isAxoScriptLoaded,
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
isGuest,
|
|
||||||
} ) => {
|
} ) => {
|
||||||
if ( ! isAxoActive && ! isAxoScriptLoaded ) {
|
if ( ! isAxoActive && ! isAxoScriptLoaded ) {
|
||||||
// Show loading spinner
|
// Show loading spinner
|
||||||
|
@ -134,7 +132,7 @@ export const updateWatermarkContent = ( {
|
||||||
createElement( Watermark, {
|
createElement( Watermark, {
|
||||||
fastlaneSdk,
|
fastlaneSdk,
|
||||||
name: 'fastlane-watermark-email',
|
name: 'fastlane-watermark-email',
|
||||||
includeAdditionalInfo: isGuest,
|
includeAdditionalInfo: true,
|
||||||
} )
|
} )
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,7 +18,8 @@ import useCustomerData from './useCustomerData';
|
||||||
*/
|
*/
|
||||||
const useAxoCleanup = () => {
|
const useAxoCleanup = () => {
|
||||||
// Get dispatch functions from the AXO store
|
// Get dispatch functions from the AXO store
|
||||||
const { setIsAxoActive, setIsGuest } = useDispatch( STORE_NAME );
|
const { setIsAxoActive, setIsGuest, setIsEmailLookupCompleted } =
|
||||||
|
useDispatch( STORE_NAME );
|
||||||
|
|
||||||
// Get functions to update WooCommerce shipping and billing addresses
|
// Get functions to update WooCommerce shipping and billing addresses
|
||||||
const {
|
const {
|
||||||
|
@ -45,6 +46,7 @@ const useAxoCleanup = () => {
|
||||||
// Reset AXO state
|
// Reset AXO state
|
||||||
setIsAxoActive( false );
|
setIsAxoActive( false );
|
||||||
setIsGuest( true );
|
setIsGuest( true );
|
||||||
|
setIsEmailLookupCompleted( false );
|
||||||
|
|
||||||
// Remove AXO UI elements
|
// Remove AXO UI elements
|
||||||
removeShippingChangeButton();
|
removeShippingChangeButton();
|
||||||
|
|
|
@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExtendingModule;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
|
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
|
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
|
||||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class BlocksModule
|
* Class BlocksModule
|
||||||
|
@ -69,8 +70,11 @@ class BlocksModule implements ServiceModule, ExtendingModule, ExecutableModule {
|
||||||
function( PaymentMethodRegistry $payment_method_registry ) use ( $c ): void {
|
function( PaymentMethodRegistry $payment_method_registry ) use ( $c ): void {
|
||||||
$payment_method_registry->register( $c->get( 'blocks.method' ) );
|
$payment_method_registry->register( $c->get( 'blocks.method' ) );
|
||||||
|
|
||||||
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
|
assert( $settings instanceof Settings );
|
||||||
|
|
||||||
// Include ACDC in the Block Checkout only in case Axo doesn't exist or is not available or the user is logged in.
|
// Include ACDC in the Block Checkout only in case Axo doesn't exist or is not available or the user is logged in.
|
||||||
if ( ! $c->has( 'axoblock.available' ) || ! $c->get( 'axoblock.available' ) || is_user_logged_in() ) {
|
if ( ( $settings->has( 'axo_enabled' ) && ! $settings->get( 'axo_enabled' ) ) || is_user_logged_in() ) {
|
||||||
$payment_method_registry->register( $c->get( 'blocks.advanced-card-method' ) );
|
$payment_method_registry->register( $c->get( 'blocks.advanced-card-method' ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ return array(
|
||||||
'FR',
|
'FR',
|
||||||
'DE',
|
'DE',
|
||||||
'GR',
|
'GR',
|
||||||
'HK',
|
|
||||||
'HU',
|
'HU',
|
||||||
'IE',
|
'IE',
|
||||||
'IT',
|
'IT',
|
||||||
|
@ -57,7 +56,6 @@ return array(
|
||||||
'PT',
|
'PT',
|
||||||
'RO',
|
'RO',
|
||||||
'SK',
|
'SK',
|
||||||
'SG',
|
|
||||||
'SI',
|
'SI',
|
||||||
'ES',
|
'ES',
|
||||||
'SE',
|
'SE',
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { useState, useEffect } from '@wordpress/element';
|
||||||
|
import useGooglepayApiToGenerateButton from '../hooks/useGooglepayApiToGenerateButton';
|
||||||
|
import usePayPalScript from '../hooks/usePayPalScript';
|
||||||
|
import useGooglepayScript from '../hooks/useGooglepayScript';
|
||||||
|
import useGooglepayConfig from '../hooks/useGooglepayConfig';
|
||||||
|
|
||||||
|
const GooglepayButton = ( { namespace, buttonConfig, ppcpConfig } ) => {
|
||||||
|
const [ buttonHtml, setButtonHtml ] = useState( '' );
|
||||||
|
const [ buttonElement, setButtonElement ] = useState( null );
|
||||||
|
const [ componentFrame, setComponentFrame ] = useState( null );
|
||||||
|
const isPayPalLoaded = usePayPalScript( namespace, ppcpConfig );
|
||||||
|
|
||||||
|
const isGooglepayLoaded = useGooglepayScript(
|
||||||
|
componentFrame,
|
||||||
|
buttonConfig,
|
||||||
|
isPayPalLoaded
|
||||||
|
);
|
||||||
|
|
||||||
|
const googlepayConfig = useGooglepayConfig( namespace, isGooglepayLoaded );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
if ( ! buttonElement ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setComponentFrame( buttonElement.ownerDocument );
|
||||||
|
}, [ buttonElement ] );
|
||||||
|
|
||||||
|
const googlepayButton = useGooglepayApiToGenerateButton(
|
||||||
|
componentFrame,
|
||||||
|
namespace,
|
||||||
|
buttonConfig,
|
||||||
|
ppcpConfig,
|
||||||
|
googlepayConfig
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
if ( googlepayButton ) {
|
||||||
|
const hideLoader =
|
||||||
|
'<style>.block-editor-iframe__html .gpay-card-info-animated-progress-bar-container {display:none !important}</style>';
|
||||||
|
setButtonHtml( googlepayButton.outerHTML + hideLoader );
|
||||||
|
}
|
||||||
|
}, [ googlepayButton ] );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
ref={ setButtonElement }
|
||||||
|
dangerouslySetInnerHTML={ { __html: buttonHtml } }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GooglepayButton;
|
|
@ -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,57 @@
|
||||||
|
import { useEffect, useState } from '@wordpress/element';
|
||||||
|
import useButtonStyles from './useButtonStyles';
|
||||||
|
|
||||||
|
const useGooglepayApiToGenerateButton = (
|
||||||
|
componentDocument,
|
||||||
|
namespace,
|
||||||
|
buttonConfig,
|
||||||
|
ppcpConfig,
|
||||||
|
googlepayConfig
|
||||||
|
) => {
|
||||||
|
const [ googlepayButton, setGooglepayButton ] = useState( null );
|
||||||
|
const buttonStyles = useButtonStyles( buttonConfig, ppcpConfig );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
if (
|
||||||
|
! componentDocument?.defaultView ||
|
||||||
|
! buttonConfig ||
|
||||||
|
! googlepayConfig
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const api = componentDocument.defaultView.google?.payments?.api;
|
||||||
|
if ( ! api ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const paymentsClient = new api.PaymentsClient( {
|
||||||
|
environment: 'TEST',
|
||||||
|
} );
|
||||||
|
|
||||||
|
const googlePayButtonOptions = {
|
||||||
|
allowedPaymentMethods: googlepayConfig.allowedPaymentMethods,
|
||||||
|
buttonColor: buttonConfig.buttonColor || 'black',
|
||||||
|
buttonType: buttonConfig.buttonType || 'pay',
|
||||||
|
buttonLocale: buttonConfig.buttonLocale || 'en',
|
||||||
|
buttonSizeMode: 'fill',
|
||||||
|
};
|
||||||
|
|
||||||
|
const button = paymentsClient.createButton( {
|
||||||
|
...googlePayButtonOptions,
|
||||||
|
onClick: ( event ) => {
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
} );
|
||||||
|
|
||||||
|
setGooglepayButton( button );
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
setGooglepayButton( null );
|
||||||
|
};
|
||||||
|
}, [ namespace, buttonConfig, ppcpConfig, googlepayConfig, buttonStyles ] );
|
||||||
|
|
||||||
|
return googlepayButton;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useGooglepayApiToGenerateButton;
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { useState, useEffect } from '@wordpress/element';
|
||||||
|
|
||||||
|
const useGooglepayConfig = ( namespace, isGooglepayLoaded ) => {
|
||||||
|
const [ googlePayConfig, setGooglePayConfig ] = useState( null );
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
const fetchConfig = async () => {
|
||||||
|
if ( ! isGooglepayLoaded ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const config = await window[ namespace ].Googlepay().config();
|
||||||
|
setGooglePayConfig( config );
|
||||||
|
} catch ( error ) {
|
||||||
|
console.error( 'Failed to fetch Google Pay config:', error );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchConfig();
|
||||||
|
}, [ namespace, isGooglepayLoaded ] );
|
||||||
|
|
||||||
|
return googlePayConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useGooglepayConfig;
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { useState, useEffect } from '@wordpress/element';
|
||||||
|
import { loadCustomScript } from '@paypal/paypal-js';
|
||||||
|
|
||||||
|
const useGooglepayScript = (
|
||||||
|
componentDocument,
|
||||||
|
buttonConfig,
|
||||||
|
isPayPalLoaded
|
||||||
|
) => {
|
||||||
|
const [ isGooglepayLoaded, setIsGooglepayLoaded ] = 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 loadGooglepayScript = 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 );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
setIsGooglepayLoaded( true );
|
||||||
|
} catch ( error ) {
|
||||||
|
console.error( 'Failed to load Googlepay script:', error );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
loadGooglepayScript();
|
||||||
|
}, [ componentDocument, buttonConfig, isPayPalLoaded ] );
|
||||||
|
|
||||||
|
return isGooglepayLoaded;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useGooglepayScript;
|
|
@ -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 += ',googlepay';
|
||||||
|
|
||||||
|
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;
|
|
@ -1,62 +1,15 @@
|
||||||
import GooglepayButton from './GooglepayButton';
|
import GooglepayButton from './Block/components/GooglepayButton';
|
||||||
import ContextHandlerFactory from './Context/ContextHandlerFactory';
|
|
||||||
|
|
||||||
class GooglepayManagerBlockEditor {
|
const GooglepayManagerBlockEditor = ( {
|
||||||
constructor( namespace, buttonConfig, ppcpConfig ) {
|
namespace,
|
||||||
this.namespace = namespace;
|
buttonConfig,
|
||||||
this.buttonConfig = buttonConfig;
|
ppcpConfig,
|
||||||
this.ppcpConfig = ppcpConfig;
|
} ) => (
|
||||||
this.googlePayConfig = null;
|
<GooglepayButton
|
||||||
this.transactionInfo = null;
|
namespace={ namespace }
|
||||||
this.contextHandler = null;
|
buttonConfig={ buttonConfig }
|
||||||
}
|
ppcpConfig={ ppcpConfig }
|
||||||
|
/>
|
||||||
init() {
|
);
|
||||||
( async () => {
|
|
||||||
await this.config();
|
|
||||||
} )();
|
|
||||||
}
|
|
||||||
|
|
||||||
async config() {
|
|
||||||
try {
|
|
||||||
// Gets GooglePay configuration of the PayPal merchant.
|
|
||||||
this.googlePayConfig = await window[ this.namespace ]
|
|
||||||
.Googlepay()
|
|
||||||
.config();
|
|
||||||
|
|
||||||
// Fetch transaction information.
|
|
||||||
this.transactionInfo = await this.fetchTransactionInfo();
|
|
||||||
|
|
||||||
const button = new GooglepayButton(
|
|
||||||
this.ppcpConfig.context,
|
|
||||||
null,
|
|
||||||
this.buttonConfig,
|
|
||||||
this.ppcpConfig,
|
|
||||||
this.contextHandler
|
|
||||||
);
|
|
||||||
|
|
||||||
button.init( this.googlePayConfig, this.transactionInfo );
|
|
||||||
} catch ( error ) {
|
|
||||||
console.error( 'Failed to initialize Google Pay:', error );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchTransactionInfo() {
|
|
||||||
try {
|
|
||||||
if ( ! this.contextHandler ) {
|
|
||||||
this.contextHandler = ContextHandlerFactory.create(
|
|
||||||
this.ppcpConfig.context,
|
|
||||||
this.buttonConfig,
|
|
||||||
this.ppcpConfig,
|
|
||||||
null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
} catch ( error ) {
|
|
||||||
console.error( 'Error fetching transaction info:', error );
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default GooglepayManagerBlockEditor;
|
export default GooglepayManagerBlockEditor;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useEffect, useState } from '@wordpress/element';
|
import { useEffect, useState } from '@wordpress/element';
|
||||||
|
import { loadCustomScript } from '@paypal/paypal-js';
|
||||||
import {
|
import {
|
||||||
registerExpressPaymentMethod,
|
registerExpressPaymentMethod,
|
||||||
registerPaymentMethod,
|
registerPaymentMethod,
|
||||||
|
@ -6,7 +7,6 @@ import {
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
|
import { loadPayPalScript } from '../../../ppcp-button/resources/js/modules/Helper/PayPalScriptLoading';
|
||||||
import GooglepayManager from './GooglepayManager';
|
import GooglepayManager from './GooglepayManager';
|
||||||
import { loadCustomScript } from '@paypal/paypal-js';
|
|
||||||
import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor';
|
import GooglepayManagerBlockEditor from './GooglepayManagerBlockEditor';
|
||||||
|
|
||||||
const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
|
const ppcpData = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
|
||||||
|
@ -20,56 +20,55 @@ if ( typeof window.PayPalCommerceGateway === 'undefined' ) {
|
||||||
window.PayPalCommerceGateway = ppcpConfig;
|
window.PayPalCommerceGateway = ppcpConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GooglePayComponent = ( props ) => {
|
const GooglePayComponent = ( { isEditing } ) => {
|
||||||
const [ bootstrapped, setBootstrapped ] = useState( false );
|
|
||||||
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
const [ paypalLoaded, setPaypalLoaded ] = useState( false );
|
||||||
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
|
const [ googlePayLoaded, setGooglePayLoaded ] = useState( false );
|
||||||
const [ manager, setManager ] = useState( null );
|
const [ manager, setManager ] = useState( null );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
// Load GooglePay SDK
|
if ( ! isEditing ) {
|
||||||
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
|
loadCustomScript( { url: buttonConfig.sdk_url } ).then( () => {
|
||||||
setGooglePayLoaded( true );
|
setGooglePayLoaded( true );
|
||||||
} );
|
|
||||||
|
|
||||||
ppcpConfig.url_params.components += ',googlepay';
|
|
||||||
|
|
||||||
// Load PayPal
|
|
||||||
loadPayPalScript( namespace, ppcpConfig )
|
|
||||||
.then( () => {
|
|
||||||
setPaypalLoaded( true );
|
|
||||||
} )
|
|
||||||
.catch( ( error ) => {
|
|
||||||
console.error( 'Failed to load PayPal script: ', error );
|
|
||||||
} );
|
} );
|
||||||
}, [] );
|
|
||||||
|
ppcpConfig.url_params.components += ',googlepay';
|
||||||
|
|
||||||
|
loadPayPalScript( namespace, ppcpConfig )
|
||||||
|
.then( () => {
|
||||||
|
setPaypalLoaded( true );
|
||||||
|
} )
|
||||||
|
.catch( ( error ) => {
|
||||||
|
console.error( 'Failed to load PayPal script: ', error );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}, [ isEditing, buttonConfig, ppcpConfig ] );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( paypalLoaded && googlePayLoaded && ! manager ) {
|
if ( ! isEditing && paypalLoaded && googlePayLoaded && ! manager ) {
|
||||||
const ManagerClass = props.isEditing
|
const newManager = new GooglepayManager(
|
||||||
? GooglepayManagerBlockEditor
|
|
||||||
: GooglepayManager;
|
|
||||||
const newManager = new ManagerClass(
|
|
||||||
namespace,
|
namespace,
|
||||||
buttonConfig,
|
buttonConfig,
|
||||||
ppcpConfig
|
ppcpConfig
|
||||||
);
|
);
|
||||||
setManager( newManager );
|
setManager( newManager );
|
||||||
}
|
}
|
||||||
}, [ paypalLoaded, googlePayLoaded, props.isEditing ] );
|
}, [ paypalLoaded, googlePayLoaded, isEditing, manager ] );
|
||||||
|
|
||||||
useEffect( () => {
|
if ( isEditing ) {
|
||||||
if ( manager && ! bootstrapped ) {
|
return (
|
||||||
setBootstrapped( true );
|
<GooglepayManagerBlockEditor
|
||||||
manager.init();
|
namespace={ namespace }
|
||||||
}
|
buttonConfig={ buttonConfig }
|
||||||
}, [ manager, bootstrapped ] );
|
ppcpConfig={ ppcpConfig }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
|
id={ buttonConfig.button.wrapper.replace( '#', '' ) }
|
||||||
className="ppcp-button-apm ppcp-button-googlepay"
|
className="ppcp-button-apm ppcp-button-googlepay"
|
||||||
></div>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,6 @@ return array(
|
||||||
'FR', // France
|
'FR', // France
|
||||||
'DE', // Germany
|
'DE', // Germany
|
||||||
'GR', // Greece
|
'GR', // Greece
|
||||||
'HK', // Hong Kong
|
|
||||||
'HU', // Hungary
|
'HU', // Hungary
|
||||||
'IE', // Ireland
|
'IE', // Ireland
|
||||||
'IT', // Italy
|
'IT', // Italy
|
||||||
|
@ -120,7 +119,6 @@ return array(
|
||||||
'PL', // Poland
|
'PL', // Poland
|
||||||
'PT', // Portugal
|
'PT', // Portugal
|
||||||
'RO', // Romania
|
'RO', // Romania
|
||||||
'SG', // Singapore
|
|
||||||
'SK', // Slovakia
|
'SK', // Slovakia
|
||||||
'SI', // Slovenia
|
'SI', // Slovenia
|
||||||
'ES', // Spain
|
'ES', // Spain
|
||||||
|
|
|
@ -72,7 +72,6 @@ return array(
|
||||||
'FR' => $default_currencies,
|
'FR' => $default_currencies,
|
||||||
'DE' => $default_currencies,
|
'DE' => $default_currencies,
|
||||||
'GR' => $default_currencies,
|
'GR' => $default_currencies,
|
||||||
'HK' => $default_currencies,
|
|
||||||
'HU' => $default_currencies,
|
'HU' => $default_currencies,
|
||||||
'IE' => $default_currencies,
|
'IE' => $default_currencies,
|
||||||
'IT' => $default_currencies,
|
'IT' => $default_currencies,
|
||||||
|
@ -87,7 +86,6 @@ return array(
|
||||||
'PT' => $default_currencies,
|
'PT' => $default_currencies,
|
||||||
'RO' => $default_currencies,
|
'RO' => $default_currencies,
|
||||||
'SK' => $default_currencies,
|
'SK' => $default_currencies,
|
||||||
'SG' => $default_currencies,
|
|
||||||
'SI' => $default_currencies,
|
'SI' => $default_currencies,
|
||||||
'ES' => $default_currencies,
|
'ES' => $default_currencies,
|
||||||
'SE' => $default_currencies,
|
'SE' => $default_currencies,
|
||||||
|
|
16
modules/ppcp-settings/composer.json
Normal file
16
modules/ppcp-settings/composer.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "woocommerce/ppcp-settings",
|
||||||
|
"type": "inpsyde-module",
|
||||||
|
"description": "Settings module",
|
||||||
|
"license": "GPL-2.0",
|
||||||
|
"require": {
|
||||||
|
"php": "^7.4 | ^8.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"WooCommerce\\PayPalCommerce\\Settings\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true
|
||||||
|
}
|
14
modules/ppcp-settings/module.php
Normal file
14
modules/ppcp-settings/module.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Settings module.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\Settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare( strict_types = 1 );
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\Settings;
|
||||||
|
|
||||||
|
return static function () : SettingsModule {
|
||||||
|
return new SettingsModule();
|
||||||
|
};
|
12
modules/ppcp-settings/package.json
Normal file
12
modules/ppcp-settings/package.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "ppcp-settings",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "GPL-3.0-or-later",
|
||||||
|
"scripts": {
|
||||||
|
"watch": "wp-scripts start --webpack-src-dir=resources/js --output-path=assets",
|
||||||
|
"build": "wp-scripts build --webpack-src-dir=resources/js --output-path=assets"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@wordpress/scripts": "^30.3.0"
|
||||||
|
}
|
||||||
|
}
|
1
modules/ppcp-settings/resources/css/style.scss
Normal file
1
modules/ppcp-settings/resources/css/style.scss
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.red {color:red;}
|
3
modules/ppcp-settings/resources/js/App.js
Normal file
3
modules/ppcp-settings/resources/js/App.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export function App() {
|
||||||
|
return <div className="red">App</div>;
|
||||||
|
}
|
7
modules/ppcp-settings/resources/js/index.js
Normal file
7
modules/ppcp-settings/resources/js/index.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { createRoot } from 'react-dom/client';
|
||||||
|
import { App } from './App';
|
||||||
|
|
||||||
|
createRoot( document.getElementById( 'ppcp-settings-container' ) ).render(
|
||||||
|
<App />
|
||||||
|
);
|
26
modules/ppcp-settings/services.php
Normal file
26
modules/ppcp-settings/services.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Settings module services.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\Settings
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare( strict_types = 1 );
|
||||||
|
|
||||||
|
namespace WooCommerce\PayPalCommerce\Settings;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'settings.url' => static function ( ContainerInterface $container ) : string {
|
||||||
|
/**
|
||||||
|
* The path cannot be false.
|
||||||
|
*
|
||||||
|
* @psalm-suppress PossiblyFalseArgument
|
||||||
|
*/
|
||||||
|
return plugins_url(
|
||||||
|
'/modules/ppcp-settings/',
|
||||||
|
dirname( realpath( __FILE__ ), 3 ) . '/woocommerce-paypal-payments.php'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
95
modules/ppcp-settings/src/SettingsModule.php
Normal file
95
modules/ppcp-settings/src/SettingsModule.php
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Settings module.
|
||||||
|
*
|
||||||
|
* @package WooCommerce\PayPalCommerce\AxoBlock
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace WooCommerce\PayPalCommerce\Settings;
|
||||||
|
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ExecutableModule;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ModuleClassNameIdTrait;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Inpsyde\Modularity\Module\ServiceModule;
|
||||||
|
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||||
|
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SettingsModule
|
||||||
|
*/
|
||||||
|
class SettingsModule implements ServiceModule, ExecutableModule {
|
||||||
|
use ModuleClassNameIdTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function services(): array {
|
||||||
|
return require __DIR__ . '/../services.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function run( ContainerInterface $container ): bool {
|
||||||
|
add_action(
|
||||||
|
'admin_enqueue_scripts',
|
||||||
|
/**
|
||||||
|
* Param types removed to avoid third-party issues.
|
||||||
|
*
|
||||||
|
* @psalm-suppress MissingClosureParamType
|
||||||
|
*/
|
||||||
|
static function( $hook_suffix ) use ( $container ) {
|
||||||
|
if ( 'woocommerce_page_wc-settings' !== $hook_suffix ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require resolves.
|
||||||
|
*
|
||||||
|
* @psalm-suppress UnresolvableInclude
|
||||||
|
*/
|
||||||
|
$script_asset_file = require dirname( realpath( __FILE__ ) ?: '', 2 ) . '/assets/index.asset.php';
|
||||||
|
|
||||||
|
$module_url = $container->get( 'settings.url' );
|
||||||
|
|
||||||
|
wp_register_script(
|
||||||
|
'ppcp-admin-settings',
|
||||||
|
$module_url . '/assets/index.js',
|
||||||
|
$script_asset_file['dependencies'],
|
||||||
|
$script_asset_file['version'],
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_enqueue_script( 'ppcp-admin-settings' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require resolves.
|
||||||
|
*
|
||||||
|
* @psalm-suppress UnresolvableInclude
|
||||||
|
*/
|
||||||
|
$style_asset_file = require dirname( realpath( __FILE__ ) ?: '', 2 ) . '/assets/style.asset.php';
|
||||||
|
|
||||||
|
wp_register_style(
|
||||||
|
'ppcp-admin-settings',
|
||||||
|
$module_url . '/assets/style-style.css',
|
||||||
|
$style_asset_file['dependencies'],
|
||||||
|
$style_asset_file['version']
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_enqueue_style( 'ppcp-admin-settings' );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'woocommerce_paypal_payments_gateway_admin_options_wrapper',
|
||||||
|
static function(): void {
|
||||||
|
global $hide_save_button;
|
||||||
|
$hide_save_button = true;
|
||||||
|
|
||||||
|
echo '<div id="ppcp-settings-container"></div>';
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
12
modules/ppcp-settings/webpack.config.js
Normal file
12
modules/ppcp-settings/webpack.config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
|
||||||
|
const path = require( 'path' );
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...defaultConfig,
|
||||||
|
...{
|
||||||
|
entry: {
|
||||||
|
index: path.resolve( process.cwd(), 'resources/js', 'index.js' ),
|
||||||
|
style: path.resolve( process.cwd(), 'resources/css', 'style.scss' ),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
10453
modules/ppcp-settings/yarn.lock
Normal file
10453
modules/ppcp-settings/yarn.lock
Normal file
File diff suppressed because it is too large
Load diff
|
@ -118,7 +118,8 @@ return array(
|
||||||
$container->get( 'wcgateway.place-order-button-text' ),
|
$container->get( 'wcgateway.place-order-button-text' ),
|
||||||
$container->get( 'api.endpoint.payment-tokens' ),
|
$container->get( 'api.endpoint.payment-tokens' ),
|
||||||
$container->get( 'vaulting.vault-v3-enabled' ),
|
$container->get( 'vaulting.vault-v3-enabled' ),
|
||||||
$container->get( 'vaulting.wc-payment-tokens' )
|
$container->get( 'vaulting.wc-payment-tokens' ),
|
||||||
|
$container->get( 'wcgateway.settings.admin-settings-enabled' )
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
'wcgateway.credit-card-gateway' => static function ( ContainerInterface $container ): CreditCardGateway {
|
||||||
|
@ -1914,4 +1915,8 @@ return array(
|
||||||
|
|
||||||
return $simple_redirect_tasks;
|
return $simple_redirect_tasks;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'wcgateway.settings.admin-settings-enabled' => static function( ContainerInterface $container ): bool {
|
||||||
|
return $container->has( 'settings.url' );
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -202,6 +202,13 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
*/
|
*/
|
||||||
private $wc_payment_tokens;
|
private $wc_payment_tokens;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether settings module is enabled.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private $admin_settings_enabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PayPalGateway constructor.
|
* PayPalGateway constructor.
|
||||||
*
|
*
|
||||||
|
@ -225,6 +232,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
* @param PaymentTokensEndpoint $payment_tokens_endpoint Payment tokens endpoint.
|
||||||
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
* @param bool $vault_v3_enabled Whether Vault v3 module is enabled.
|
||||||
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens.
|
* @param WooCommercePaymentTokens $wc_payment_tokens WooCommerce payment tokens.
|
||||||
|
* @param bool $admin_settings_enabled Whether settings module is enabled.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SettingsRenderer $settings_renderer,
|
SettingsRenderer $settings_renderer,
|
||||||
|
@ -246,7 +254,8 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
string $place_order_button_text,
|
string $place_order_button_text,
|
||||||
PaymentTokensEndpoint $payment_tokens_endpoint,
|
PaymentTokensEndpoint $payment_tokens_endpoint,
|
||||||
bool $vault_v3_enabled,
|
bool $vault_v3_enabled,
|
||||||
WooCommercePaymentTokens $wc_payment_tokens
|
WooCommercePaymentTokens $wc_payment_tokens,
|
||||||
|
bool $admin_settings_enabled
|
||||||
) {
|
) {
|
||||||
$this->id = self::ID;
|
$this->id = self::ID;
|
||||||
$this->settings_renderer = $settings_renderer;
|
$this->settings_renderer = $settings_renderer;
|
||||||
|
@ -270,6 +279,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
$this->payment_tokens_endpoint = $payment_tokens_endpoint;
|
||||||
$this->vault_v3_enabled = $vault_v3_enabled;
|
$this->vault_v3_enabled = $vault_v3_enabled;
|
||||||
$this->wc_payment_tokens = $wc_payment_tokens;
|
$this->wc_payment_tokens = $wc_payment_tokens;
|
||||||
|
$this->admin_settings_enabled = $admin_settings_enabled;
|
||||||
|
|
||||||
$default_support = array(
|
$default_support = array(
|
||||||
'products',
|
'products',
|
||||||
|
@ -745,6 +755,17 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the parent admin_options method.
|
||||||
|
*/
|
||||||
|
public function admin_options() {
|
||||||
|
if ( ! $this->admin_settings_enabled ) {
|
||||||
|
parent::admin_options();
|
||||||
|
}
|
||||||
|
|
||||||
|
do_action( 'woocommerce_paypal_payments_gateway_admin_options_wrapper', $this );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the settings renderer.
|
* Returns the settings renderer.
|
||||||
*
|
*
|
||||||
|
|
2
package-lock.json
generated
2
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "woocommerce-paypal-payments",
|
"name": "woocommerce-paypal-payments",
|
||||||
"version": "2.9.2",
|
"version": "2.9.3",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "woocommerce-paypal-payments",
|
"name": "woocommerce-paypal-payments",
|
||||||
"version": "2.9.2",
|
"version": "2.9.3",
|
||||||
"description": "WooCommerce PayPal Payments",
|
"description": "WooCommerce PayPal Payments",
|
||||||
"repository": "https://github.com/woocommerce/woocommerce-paypal-payments",
|
"repository": "https://github.com/woocommerce/woocommerce-paypal-payments",
|
||||||
"license": "GPL-2.0",
|
"license": "GPL-2.0",
|
||||||
|
@ -26,6 +26,7 @@
|
||||||
"install:modules:ppcp-onboarding": "cd modules/ppcp-onboarding && yarn install",
|
"install:modules:ppcp-onboarding": "cd modules/ppcp-onboarding && yarn install",
|
||||||
"install:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn install",
|
"install:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn install",
|
||||||
"install:modules:ppcp-compat": "cd modules/ppcp-compat && yarn install",
|
"install:modules:ppcp-compat": "cd modules/ppcp-compat && yarn install",
|
||||||
|
"install:modules:ppcp-settings": "cd modules/ppcp-settings && yarn install",
|
||||||
"install:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn install",
|
"install:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn install",
|
||||||
"build:modules:ppcp-admin-notices": "cd modules/ppcp-admin-notices && yarn run build",
|
"build:modules:ppcp-admin-notices": "cd modules/ppcp-admin-notices && yarn run build",
|
||||||
"build:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run build",
|
"build:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run build",
|
||||||
|
@ -47,6 +48,7 @@
|
||||||
"build:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run build",
|
"build:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run build",
|
||||||
"build:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run build",
|
"build:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run build",
|
||||||
"build:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run build",
|
"build:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run build",
|
||||||
|
"build:modules:ppcp-settings": "cd modules/ppcp-settings && yarn run build",
|
||||||
"build:modules": "run-p build:modules:*",
|
"build:modules": "run-p build:modules:*",
|
||||||
"watch:modules:ppcp-admin-notices": "cd modules/ppcp-admin-notices && yarn run watch",
|
"watch:modules:ppcp-admin-notices": "cd modules/ppcp-admin-notices && yarn run watch",
|
||||||
"watch:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run watch",
|
"watch:modules:ppcp-applepay": "cd modules/ppcp-applepay && yarn run watch",
|
||||||
|
@ -68,6 +70,7 @@
|
||||||
"watch:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run watch",
|
"watch:modules:ppcp-card-fields": "cd modules/ppcp-card-fields && yarn run watch",
|
||||||
"watch:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run watch",
|
"watch:modules:ppcp-compat": "cd modules/ppcp-compat && yarn run watch",
|
||||||
"watch:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run watch",
|
"watch:modules:ppcp-uninstall": "cd modules/ppcp-uninstall && yarn run watch",
|
||||||
|
"watch:modules:ppcp-settings": "cd modules/ppcp-settings && yarn run watch",
|
||||||
"watch:modules": "run-p watch:modules:*",
|
"watch:modules": "run-p watch:modules:*",
|
||||||
"ddev:setup": "ddev start && ddev orchestrate",
|
"ddev:setup": "ddev start && ddev orchestrate",
|
||||||
"ddev:start": "ddev start",
|
"ddev:start": "ddev start",
|
||||||
|
|
27
readme.txt
27
readme.txt
|
@ -4,7 +4,7 @@ Tags: woocommerce, paypal, payments, ecommerce, credit card
|
||||||
Requires at least: 6.3
|
Requires at least: 6.3
|
||||||
Tested up to: 6.6
|
Tested up to: 6.6
|
||||||
Requires PHP: 7.4
|
Requires PHP: 7.4
|
||||||
Stable tag: 2.9.2
|
Stable tag: 2.9.3
|
||||||
License: GPLv2
|
License: GPLv2
|
||||||
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
|
||||||
|
@ -179,6 +179,31 @@ If you encounter issues with the PayPal buttons not appearing after an update, p
|
||||||
|
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 2.9.3 - 2024-10-15 =
|
||||||
|
* Fix - Multi-currency support #2667
|
||||||
|
* Fix - "0.00" amount in Google Pay for virtual products #2636
|
||||||
|
* Fix - Unsuccessfully payment from product page with Apple Pay button #2643
|
||||||
|
* Fix - Button Unlinking PayPal Subscriptions plan does not showing for simple subscription #2618
|
||||||
|
* Fix - Declare tokenization for ACDC only when vaulting enabled #2581
|
||||||
|
* Fix - Classic shortcode block type checks #2608
|
||||||
|
* Fix - PUI error in editor #2580
|
||||||
|
* Fix - Add a new namespaced script loader for ApplePay #2682 #2675
|
||||||
|
* Fix - Axo Block: Fix the Fastlane modal info message text overflow issue #2663
|
||||||
|
* Fix - Add Custom Placeholder Handling when rendering the card fields #2651
|
||||||
|
* Fix - Use the PayPal icons instead of WC ones #2639
|
||||||
|
* Fix - Google Pay preview config and style #2661
|
||||||
|
* Fix - Improve context detection #2631
|
||||||
|
* Fix - Check that get_the_ID is valid before using #2573
|
||||||
|
* Fix - Axo Block: Always display the Fastlane watermark in the includeAdditionalInfo mode #2690
|
||||||
|
* Fix - Axo Block: Display card fields for authenticated cardless profiles #2672
|
||||||
|
* Fix - Google Pay: Fix button preview in the editor #2688
|
||||||
|
* Fix - ACDC gateway not visible on the block Checkout for logged-out users #2693
|
||||||
|
* Enhancement - Enhancement - Add Fastlane support for Checkout block
|
||||||
|
* Enhancement - Multiple calls to POST /v1/oauth2/token?grant_type=client_credentials&response_type=id_token #2671
|
||||||
|
* Enhancement - Fastlane update shipping options & taxes when changing address #2665
|
||||||
|
* Enhancement - Axo: Remove Axo from the Checkout block in the editor and add an ACDC card preview #2662
|
||||||
|
* Enhancement - Set email when creating order for express payment #2577
|
||||||
|
|
||||||
= 2.9.2 - 2024-10-01 =
|
= 2.9.2 - 2024-10-01 =
|
||||||
* Enhancement - Add Fastlane support for Classic Checkout
|
* Enhancement - Add Fastlane support for Classic Checkout
|
||||||
* Fix - Fatal error when Pay Later messaging configurator was disabled with a code snippet
|
* Fix - Fatal error when Pay Later messaging configurator was disabled with a code snippet
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace WooCommerce\PayPalCommerce\ApiClient\Endpoint;
|
|
||||||
|
|
||||||
use Mockery;
|
|
||||||
use Psr\Log\LoggerInterface;
|
|
||||||
use Requests_Utility_CaseInsensitiveDictionary;
|
|
||||||
use WC_Order;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Authentication\Bearer;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Token;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
|
||||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
|
|
||||||
use WooCommerce\PayPalCommerce\TestCase;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\FraudNet\FraudNet;
|
|
||||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice\PaymentSource;
|
|
||||||
use function Brain\Monkey\Functions\expect;
|
|
||||||
use function Brain\Monkey\Functions\when;
|
|
||||||
|
|
||||||
class PayUponInvoiceOrderEndpointTest extends TestCase
|
|
||||||
{
|
|
||||||
private $bearer;
|
|
||||||
private $orderFactory;
|
|
||||||
private $fraudnet;
|
|
||||||
private $logger;
|
|
||||||
private $testee;
|
|
||||||
|
|
||||||
public function setUp(): void
|
|
||||||
{
|
|
||||||
parent::setUp();
|
|
||||||
|
|
||||||
$this->bearer = Mockery::mock(Bearer::class);
|
|
||||||
$token = Mockery::mock(Token::class);
|
|
||||||
$token->shouldReceive('token')->andReturn('');
|
|
||||||
$this->bearer->shouldReceive('bearer')->andReturn($token);
|
|
||||||
|
|
||||||
$this->orderFactory = Mockery::mock(OrderFactory::class);
|
|
||||||
$this->fraudnet = Mockery::mock(FraudNet::class);
|
|
||||||
$this->logger = Mockery::mock(LoggerInterface::class);
|
|
||||||
|
|
||||||
$this->testee = new PayUponInvoiceOrderEndpoint(
|
|
||||||
'',
|
|
||||||
$this->bearer,
|
|
||||||
$this->orderFactory,
|
|
||||||
$this->fraudnet,
|
|
||||||
$this->logger
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCreateOrder()
|
|
||||||
{
|
|
||||||
$this->markTestSkipped('must be revisited.');
|
|
||||||
list($items, $paymentSource, $headers) = $this->setStubs();
|
|
||||||
|
|
||||||
$response = [
|
|
||||||
'body' => '{"is_correct":true}',
|
|
||||||
'headers' => $headers,
|
|
||||||
];
|
|
||||||
expect('wp_remote_get')->andReturn($response);
|
|
||||||
expect('wp_remote_retrieve_response_code')->with($response)->andReturn(200);
|
|
||||||
|
|
||||||
$this->logger->shouldReceive('debug');
|
|
||||||
|
|
||||||
$wc_order = Mockery::mock(WC_Order::class);
|
|
||||||
|
|
||||||
|
|
||||||
$result = $this->testee->create($items, $paymentSource, $wc_order );
|
|
||||||
$this->assertInstanceOf(Order::class, $result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCreateOrderWpError()
|
|
||||||
{
|
|
||||||
$this->markTestSkipped('must be revisited.');
|
|
||||||
list($items, $paymentSource) = $this->setStubsForError();
|
|
||||||
|
|
||||||
$wpError = Mockery::mock(\WP_Error::class);
|
|
||||||
$wpError->shouldReceive('get_error_messages')->andReturn(['foo']);
|
|
||||||
$wpError->shouldReceive('get_error_message')->andReturn('foo');
|
|
||||||
expect('wp_remote_get')->andReturn($wpError);
|
|
||||||
|
|
||||||
$this->logger->shouldReceive('debug');
|
|
||||||
$wc_order = Mockery::mock(WC_Order::class);
|
|
||||||
|
|
||||||
$this->expectException(\RuntimeException::class);
|
|
||||||
$this->testee->create($items, $paymentSource, $wc_order);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCreateOrderApiError()
|
|
||||||
{
|
|
||||||
$this->markTestSkipped('must be revisited.');
|
|
||||||
list($items, $paymentSource) = $this->setStubsForError();
|
|
||||||
|
|
||||||
$headers = Mockery::mock(Requests_Utility_CaseInsensitiveDictionary::class);
|
|
||||||
$headers->shouldReceive('getAll');
|
|
||||||
$response = [
|
|
||||||
'body' => '{"is_correct":true}',
|
|
||||||
'headers' => $headers,
|
|
||||||
];
|
|
||||||
|
|
||||||
when('get_bloginfo')->justReturn('de-DE');
|
|
||||||
expect('wp_remote_get')->andReturn($response);
|
|
||||||
expect('wp_remote_retrieve_response_code')->with($response)->andReturn(500);
|
|
||||||
|
|
||||||
$this->logger->shouldReceive('debug');
|
|
||||||
|
|
||||||
$wc_order = Mockery::mock(WC_Order::class);
|
|
||||||
$this->expectException(PayPalApiException::class);
|
|
||||||
$this->testee->create($items, $paymentSource, $wc_order);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function setStubs(): array
|
|
||||||
{
|
|
||||||
$order = Mockery::mock(Order::class);
|
|
||||||
$this->orderFactory
|
|
||||||
->expects('from_paypal_response')
|
|
||||||
->andReturnUsing(function (\stdClass $object) use ($order): ?Order {
|
|
||||||
return ($object->is_correct) ? $order : null;
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->fraudnet->shouldReceive('session_id')->andReturn('');
|
|
||||||
|
|
||||||
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
|
|
||||||
$purchaseUnit->shouldReceive('to_array')->andReturn([
|
|
||||||
'items' => [],
|
|
||||||
]);
|
|
||||||
$items = [$purchaseUnit];
|
|
||||||
|
|
||||||
$paymentSource = Mockery::mock(PaymentSource::class);
|
|
||||||
$paymentSource->shouldReceive('to_array')->andReturn([]);
|
|
||||||
|
|
||||||
$headers = Mockery::mock(Requests_Utility_CaseInsensitiveDictionary::class);
|
|
||||||
$headers->shouldReceive('getAll');
|
|
||||||
return array($items, $paymentSource, $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function setStubsForError(): array
|
|
||||||
{
|
|
||||||
$this->fraudnet->shouldReceive('session_id')->andReturn('');
|
|
||||||
$purchaseUnit = Mockery::mock(PurchaseUnit::class);
|
|
||||||
$purchaseUnit->shouldReceive('to_array')->andReturn([
|
|
||||||
'items' => [],
|
|
||||||
]);
|
|
||||||
$items = [$purchaseUnit];
|
|
||||||
$paymentSource = Mockery::mock(PaymentSource::class);
|
|
||||||
$paymentSource->shouldReceive('to_array')->andReturn([]);
|
|
||||||
return array($items, $paymentSource);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -123,7 +123,8 @@ class WcGatewayTest extends TestCase
|
||||||
'Pay via PayPal',
|
'Pay via PayPal',
|
||||||
$this->paymentTokensEndpoint,
|
$this->paymentTokensEndpoint,
|
||||||
$this->vaultV3Enabled,
|
$this->vaultV3Enabled,
|
||||||
$this->wcPaymentTokens
|
$this->wcPaymentTokens,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* Plugin Name: WooCommerce PayPal Payments
|
* Plugin Name: WooCommerce PayPal Payments
|
||||||
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
* Plugin URI: https://woocommerce.com/products/woocommerce-paypal-payments/
|
||||||
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
* Description: PayPal's latest complete payments processing solution. Accept PayPal, Pay Later, credit/debit cards, alternative digital wallets local payment types and bank accounts. Turn on only PayPal options or process a full suite of payment methods. Enable global transaction with extensive currency and country coverage.
|
||||||
* Version: 2.9.2
|
* Version: 2.9.3
|
||||||
* Author: WooCommerce
|
* Author: WooCommerce
|
||||||
* Author URI: https://woocommerce.com/
|
* Author URI: https://woocommerce.com/
|
||||||
* License: GPL-2.0
|
* License: GPL-2.0
|
||||||
|
@ -26,7 +26,7 @@ define( 'PAYPAL_API_URL', 'https://api-m.paypal.com' );
|
||||||
define( 'PAYPAL_URL', 'https://www.paypal.com' );
|
define( 'PAYPAL_URL', 'https://www.paypal.com' );
|
||||||
define( 'PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com' );
|
define( 'PAYPAL_SANDBOX_API_URL', 'https://api-m.sandbox.paypal.com' );
|
||||||
define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' );
|
define( 'PAYPAL_SANDBOX_URL', 'https://www.sandbox.paypal.com' );
|
||||||
define( 'PAYPAL_INTEGRATION_DATE', '2024-09-30' );
|
define( 'PAYPAL_INTEGRATION_DATE', '2024-10-11' );
|
||||||
define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' );
|
define( 'PPCP_PAYPAL_BN_CODE', 'Woo_PPCP' );
|
||||||
|
|
||||||
! defined( 'CONNECT_WOO_CLIENT_ID' ) && define( 'CONNECT_WOO_CLIENT_ID', 'AcCAsWta_JTL__OfpjspNyH7c1GGHH332fLwonA5CwX4Y10mhybRZmHLA0GdRbwKwjQIhpDQy0pluX_P' );
|
! defined( 'CONNECT_WOO_CLIENT_ID' ) && define( 'CONNECT_WOO_CLIENT_ID', 'AcCAsWta_JTL__OfpjspNyH7c1GGHH332fLwonA5CwX4Y10mhybRZmHLA0GdRbwKwjQIhpDQy0pluX_P' );
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue