From 368ad49d16ae623d2ec42c3deb49f8dd717295a3 Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Wed, 18 Sep 2024 17:33:27 +0200
Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=8E=A8=20Minor=20changes=20in=20comme?=
=?UTF-8?q?nt=20linebreaks?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../resources/js/GooglepayButton.js | 35 ++++++-------------
1 file changed, 11 insertions(+), 24 deletions(-)
diff --git a/modules/ppcp-googlepay/resources/js/GooglepayButton.js b/modules/ppcp-googlepay/resources/js/GooglepayButton.js
index d4d9df55f..97bfa6d2c 100644
--- a/modules/ppcp-googlepay/resources/js/GooglepayButton.js
+++ b/modules/ppcp-googlepay/resources/js/GooglepayButton.js
@@ -5,7 +5,6 @@ import {
import PaymentButton from '../../../ppcp-button/resources/js/modules/Renderer/PaymentButton';
import widgetBuilder from '../../../ppcp-button/resources/js/modules/Renderer/WidgetBuilder';
import UpdatePaymentData from './Helper/UpdatePaymentData';
-import TransactionInfo from './Helper/TransactionInfo';
import { PaymentMethods } from '../../../ppcp-button/resources/js/modules/Helper/CheckoutMethodState';
import { setPayerData } from '../../../ppcp-button/resources/js/modules/Helper/PayerData';
import moduleStorage from './Helper/GooglePayStorage';
@@ -42,17 +41,11 @@ import moduleStorage from './Helper/GooglePayStorage';
*
* @see https://developers.google.com/pay/api/web/reference/client
* @typedef {Object} PaymentsClient
- * @property {Function} createButton - The convenience method is used to
- * generate a Google Pay payment button styled with the latest Google Pay branding for
- * insertion into a webpage.
- * @property {Function} isReadyToPay - Use the isReadyToPay(isReadyToPayRequest)
- * method to determine a user's ability to return a form of payment from the Google Pay API.
- * @property {(Object) => Promise} loadPaymentData - This method presents a Google Pay payment
- * sheet that allows selection of a payment method and optionally configured parameters
- * @property {Function} onPaymentAuthorized - This method is called when a payment is
- * authorized in the payment sheet.
- * @property {Function} onPaymentDataChanged - This method handles payment data changes
- * in the payment sheet such as shipping address and shipping options.
+ * @property {Function} createButton - The convenience method is used to generate a Google Pay payment button styled with the latest Google Pay branding for insertion into a webpage.
+ * @property {Function} isReadyToPay - Use the isReadyToPay(isReadyToPayRequest) method to determine a user's ability to return a form of payment from the Google Pay API.
+ * @property {(Object) => Promise} loadPaymentData - This method presents a Google Pay payment sheet that allows selection of a payment method and optionally configured parameters
+ * @property {Function} onPaymentAuthorized - This method is called when a payment is authorized in the payment sheet.
+ * @property {Function} onPaymentDataChanged - This method handles payment data changes in the payment sheet such as shipping address and shipping options.
*/
/**
@@ -62,18 +55,12 @@ import moduleStorage from './Helper/GooglePayStorage';
* @typedef {Object} TransactionInfo
* @property {string} currencyCode - Required. The ISO 4217 alphabetic currency code.
* @property {string} countryCode - Optional. required for EEA countries,
- * @property {string} transactionId - Optional. A unique ID that identifies a facilitation
- * attempt. Highly encouraged for troubleshooting.
- * @property {string} totalPriceStatus - Required. [ESTIMATED|FINAL] The status of the total price
- * used:
- * @property {string} totalPrice - Required. Total monetary value of the transaction with an
- * optional decimal precision of two decimal places.
- * @property {Array} displayItems - Optional. A list of cart items shown in the payment sheet
- * (e.g. subtotals, sales taxes, shipping charges, discounts etc.).
- * @property {string} totalPriceLabel - Optional. Custom label for the total price within the
- * display items.
- * @property {string} checkoutOption - Optional. Affects the submit button text displayed in the
- * Google Pay payment sheet.
+ * @property {string} transactionId - Optional. A unique ID that identifies a facilitation attempt. Highly encouraged for troubleshooting.
+ * @property {string} totalPriceStatus - Required. [ESTIMATED|FINAL] The status of the total price used.
+ * @property {string} totalPrice - Required. Total monetary value of the transaction with an optional decimal precision of two decimal places.
+ * @property {Array} displayItems - Optional. A list of cart items shown in the payment sheet (e.g. subtotals, sales taxes, shipping charges, discounts etc.).
+ * @property {string} totalPriceLabel - Optional. Custom label for the total price within the display items.
+ * @property {string} checkoutOption - Optional. Affects the submit button text displayed in the Google Pay payment sheet.
*/
function payerDataFromPaymentResponse( response ) {
From 643a23c6e02f2a13a9b6dbd7a8181c36d0875ca2 Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Wed, 18 Sep 2024 17:34:20 +0200
Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20the=200-amount=20bug?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When shipping is disabled, the shippingFee is `undefined` which also resulted in the amount to become `NaN`
---
modules/ppcp-googlepay/resources/js/Helper/TransactionInfo.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/modules/ppcp-googlepay/resources/js/Helper/TransactionInfo.js b/modules/ppcp-googlepay/resources/js/Helper/TransactionInfo.js
index 9216ad7c9..de62926ad 100644
--- a/modules/ppcp-googlepay/resources/js/Helper/TransactionInfo.js
+++ b/modules/ppcp-googlepay/resources/js/Helper/TransactionInfo.js
@@ -8,6 +8,8 @@ export default class TransactionInfo {
this.#country = country;
this.#currency = currency;
+ shippingFee = this.toAmount( shippingFee );
+ total = this.toAmount( total );
this.shippingFee = shippingFee;
this.amount = total - shippingFee;
}
From 5891d80f75b143d98980895d36d32429a87c4523 Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Mon, 23 Sep 2024 13:50:44 +0200
Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=8E=A8=20Code=20style=20changes=20&?=
=?UTF-8?q?=20cleanup?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Remove unused imports
- Use state instead of global window-variable (continuationFilled)
- Apply codestyle rules (spaces, change one let to const)
---
.../resources/js/checkout-block.js | 41 +++++++++----------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js
index d1b6ad990..4bec20aa6 100644
--- a/modules/ppcp-blocks/resources/js/checkout-block.js
+++ b/modules/ppcp-blocks/resources/js/checkout-block.js
@@ -19,8 +19,6 @@ import { PayPalScriptProvider, PayPalButtons } from '@paypal/react-paypal-js';
import { normalizeStyleForFundingSource } from '../../../ppcp-button/resources/js/modules/Helper/Style';
import buttonModuleWatcher from '../../../ppcp-button/resources/js/modules/ButtonModuleWatcher';
import BlockCheckoutMessagesBootstrap from './Bootstrap/BlockCheckoutMessagesBootstrap';
-import { keysToCamelCase } from '../../../ppcp-button/resources/js/modules/Helper/Utils';
-import { handleShippingOptionsChange } from '../../../ppcp-button/resources/js/modules/Helper/ShippingHandler';
const config = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
window.ppcpFundingSource = config.fundingSource;
@@ -46,6 +44,7 @@ const PayPalComponent = ( {
const { responseTypes } = emitResponse;
const [ paypalOrder, setPaypalOrder ] = useState( null );
+ const [ continuationFilled, setContinuationFilled ] = useState( false );
const [ gotoContinuationOnError, setGotoContinuationOnError ] =
useState( false );
@@ -65,13 +64,10 @@ const PayPalComponent = ( {
useEffect( () => {
// fill the form if in continuation (for product or mini-cart buttons)
- if (
- ! config.scriptData.continuation ||
- ! config.scriptData.continuation.order ||
- window.ppcpContinuationFilled
- ) {
+ if ( continuationFilled || ! config.scriptData.continuation?.order ) {
return;
}
+
try {
const paypalAddresses = paypalOrderToWcAddresses(
config.scriptData.continuation.order
@@ -80,9 +76,11 @@ const PayPalComponent = ( {
.select( 'wc/store/cart' )
.getCustomerData();
const addresses = mergeWcAddress( wcAddresses, paypalAddresses );
+
wp.data
.dispatch( 'wc/store/cart' )
.setBillingAddress( addresses.billingAddress );
+
if ( shippingData.needsShipping ) {
wp.data
.dispatch( 'wc/store/cart' )
@@ -92,9 +90,10 @@ const PayPalComponent = ( {
// sometimes the PayPal address is missing, skip in this case.
console.log( err );
}
+
// this useEffect should run only once, but adding this in case of some kind of full re-rendering
- window.ppcpContinuationFilled = true;
- }, [] );
+ setContinuationFilled( true );
+ }, [ shippingData, continuationFilled ] );
const createOrder = async ( data, actions ) => {
try {
@@ -364,19 +363,19 @@ const PayPalComponent = ( {
};
const shouldHandleShippingInPayPal = () => {
- return shouldskipFinalConfirmation() && config.needShipping
+ return shouldskipFinalConfirmation() && config.needShipping;
};
- const shouldskipFinalConfirmation = () => {
- if ( config.finalReviewEnabled ) {
- return false;
- }
+ const shouldskipFinalConfirmation = () => {
+ if ( config.finalReviewEnabled ) {
+ return false;
+ }
- return (
- window.ppcpFundingSource !== 'venmo' ||
- ! config.scriptData.vaultingEnabled
- );
- };
+ return (
+ window.ppcpFundingSource !== 'venmo' ||
+ ! config.scriptData.vaultingEnabled
+ );
+ };
let handleShippingOptionsChange = null;
let handleShippingAddressChange = null;
@@ -610,11 +609,11 @@ const PayPalComponent = ( {
}
return ( data, actions ) => {
- let shippingAddressChange = shouldHandleShippingInPayPal()
+ const shippingAddressChange = shouldHandleShippingInPayPal()
? handleShippingAddressChange( data, actions )
: null;
- return shippingAddressChange;
+ return shippingAddressChange;
};
};
From c852bc92b50b38850ea6d0484e26b9ef797bd515 Mon Sep 17 00:00:00 2001
From: Philipp Stracker
Date: Mon, 23 Sep 2024 17:14:28 +0200
Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=90=9B=20Fix=20express=20payment=20er?=
=?UTF-8?q?ror=20in=20block=20cart?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../resources/js/checkout-block.js | 26 ++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/modules/ppcp-blocks/resources/js/checkout-block.js b/modules/ppcp-blocks/resources/js/checkout-block.js
index 4bec20aa6..21d959a4f 100644
--- a/modules/ppcp-blocks/resources/js/checkout-block.js
+++ b/modules/ppcp-blocks/resources/js/checkout-block.js
@@ -24,9 +24,10 @@ const config = wc.wcSettings.getSetting( 'ppcp-gateway_data' );
window.ppcpFundingSource = config.fundingSource;
let registeredContext = false;
-
let paypalScriptPromise = null;
+const PAYPAL_GATEWAY_ID = 'ppcp-gateway';
+
const PayPalComponent = ( {
onClick,
onClose,
@@ -62,6 +63,27 @@ const PayPalComponent = ( {
? `${ config.id }-${ fundingSource }`
: config.id;
+ /**
+ * The block cart displays express checkout buttons. Those buttons are handled by the
+ * PAYPAL_GATEWAY_ID method on the server ("PayPal Smart Buttons").
+ *
+ * A possible bug in WooCommerce does not use the correct payment method ID for the express
+ * payment buttons inside the cart, but sends the ID of the _first_ active payment method.
+ *
+ * This function uses an internal WooCommerce dispatcher method to set the correct method ID.
+ */
+ const enforcePaymentMethodForCart = () => {
+ // Do nothing, unless we're handling block cart express payment buttons.
+ if ( 'cart-block' !== config.scriptData.context ) {
+ return;
+ }
+
+ // Set the active payment method to PAYPAL_GATEWAY_ID.
+ wp.data
+ .dispatch( 'wc/store/payment' )
+ .__internalSetActivePaymentMethod( PAYPAL_GATEWAY_ID, {} );
+ };
+
useEffect( () => {
// fill the form if in continuation (for product or mini-cart buttons)
if ( continuationFilled || ! config.scriptData.continuation?.order ) {
@@ -230,6 +252,7 @@ const PayPalComponent = ( {
location.href = getCheckoutRedirectUrl();
} else {
setGotoContinuationOnError( true );
+ enforcePaymentMethodForCart();
onSubmit();
}
} catch ( err ) {
@@ -321,6 +344,7 @@ const PayPalComponent = ( {
location.href = getCheckoutRedirectUrl();
} else {
setGotoContinuationOnError( true );
+ enforcePaymentMethodForCart();
onSubmit();
}
} catch ( err ) {