Skip to content

Commit 40bba7d

Browse files
committed
Merge remote-tracking branch 'origin/release/8.5.0' into trunk
2 parents c0b38dd + 5d78570 commit 40bba7d

File tree

83 files changed

+3199
-550
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+3199
-550
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,5 @@ Please follow the following guidelines when writing testing instructions:
4848
**Post merge**
4949

5050
- [ ] Added testing instructions to the [Release Testing Instructions wiki page](https://github.com/woocommerce/woocommerce-gateway-stripe/wiki/Release-Testing-Instructions) (or does not apply)
51+
- [ ] Added the [needs docs label](https://github.com/woocommerce/woocommerce-gateway-stripe/labels?q=docs) (or does not apply)
52+
- [ ] Included this PR in the Release Thread scope (or does not apply)

changelog.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
*** Changelog ***
22

3+
= 8.5.0 - 2024-07-11 =
4+
* Tweak - Remove Giropay from the list of payment methods (for all versions) due deprecation.
5+
* Tweak - Additional visual improvement for the webhook configuration notice.
6+
* Add - Allow changing display order of payment methods in the new checkout experience.
7+
* Add - Update the payment method associated with a subscription to a PaymentMethod when it's using a Stripe Source that was migrated to PaymentMethods.
8+
* Fix - Prevent subscriptions using Legacy SEPA from switching to Manual Renewal when disabling the Legacy experience.
9+
* Tweak - Add a notice in checkout for Cash App transactions above 2000 USD to inform customers about the decline risk.
10+
* Tweak - Improve the display of warning messages related to webhook configuration.
11+
* Fix - When using a saved payment method, update the payment method's address immediately upon checkout. Fixes issues where Stripe may throw address validation errors.
12+
* Tweak - Add a statement descriptor preview for Cash App Payments.
13+
* Add - Allow customizing the title and description of the UPE payment methods.
14+
* Fix - Ensure payments via redirect are processed through the webhook if the redirect never occurs. Resolves issues of orders being left as pending payment.
15+
* Add - Introduce a way for store managers to automatically configure webhooks on their Stripe account with a single button in the admin settings.
16+
* Fix - Ensure subscriptions purchased with iDEAL or Bancontact are correctly set to SEPA debit prior to processing the intitial payment.
17+
* Tweak - Stripe API version updated to support 2024-06-20.
18+
* Fix - Ensure SEPA tokens are attached to customers in the legacy checkout experience when the payment method is saved. This addresses subscription recurring payment "off-session" errors with SEPA.
19+
* Fix - Prevent saved SEPA Sources from being displayed as available payment methods when the Updated checkout experience is enabled.
20+
321
= 8.4.0 - 2024-06-13 =
422
* Tweak - Resets the list of payment methods when any Stripe key is updated.
523
* Fix - Removes the list of saved payment methods when the setting is disabled.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* Call a function when an element is available in the DOM.
3+
*
4+
* @param {string} selector The selector to look for.
5+
* @param {Function} callable fThe function to call when the element is available.
6+
* @param {Array} params The parameters to pass to the callable function.
7+
*/
8+
export function callWhenElementIsAvailable( selector, callable, params = [] ) {
9+
const checkoutBlock = document.querySelector(
10+
'[data-block-name="woocommerce/checkout"]'
11+
);
12+
13+
if ( ! checkoutBlock ) {
14+
return;
15+
}
16+
17+
const observer = new MutationObserver( ( mutationList, obs ) => {
18+
if ( document.querySelector( selector ) ) {
19+
// Element found, run the function and disconnect the observer.
20+
callable( ...params );
21+
obs.disconnect();
22+
}
23+
} );
24+
25+
observer.observe( checkoutBlock, {
26+
childList: true,
27+
subtree: true,
28+
} );
29+
}

client/blocks/upe/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const api = new WCStripeAPI(
2525
const upeMethods = getPaymentMethodsConstants();
2626
Object.entries( getBlocksConfiguration()?.paymentMethodsConfig )
2727
.filter( ( [ upeName ] ) => upeName !== 'link' )
28+
.filter( ( [ upeName ] ) => upeName !== 'giropay' ) // Skip giropay as it was deprecated by Jun, 30th 2024.
2829
.forEach( ( [ upeName, upeConfig ] ) => {
2930
let iconName = upeName;
3031

@@ -44,13 +45,15 @@ Object.entries( getBlocksConfiguration()?.paymentMethodsConfig )
4445
upeName,
4546
upeMethods,
4647
api,
48+
upeConfig.description,
4749
upeConfig.testingInstructions,
4850
upeConfig.showSaveOption ?? false
4951
),
5052
edit: getDeferredIntentCreationUPEFields(
5153
upeName,
5254
upeMethods,
5355
api,
56+
upeConfig.description,
5457
upeConfig.testingInstructions,
5558
upeConfig.showSaveOption ?? false
5659
),

client/blocks/upe/token-label-updater.js

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* WC_Stripe_Payment_Tokens::get_token_label_overrides_for_checkout().
1212
*/
1313
import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
14+
import { callWhenElementIsAvailable } from 'wcstripe/blocks/upe/call-when-element-is-available';
1415

1516
/**
1617
* Determines whether there are token label overrides.
@@ -57,26 +58,6 @@ export function updateTokenLabelsWhenLoaded() {
5758
if ( hasTokenElements ) {
5859
updateTokenLabels();
5960
} else {
60-
// Tokens are not loaded yet, set up an observer to trigger once they have been mounted.
61-
const checkoutBlock = document.querySelector(
62-
'[data-block-name="woocommerce/checkout"]'
63-
);
64-
65-
if ( ! checkoutBlock ) {
66-
return;
67-
}
68-
69-
const observer = new MutationObserver( ( mutationList, obs ) => {
70-
if ( document.querySelector( selector ) ) {
71-
// Tokens found, run the function and disconnect the observer.
72-
updateTokenLabels();
73-
obs.disconnect();
74-
}
75-
} );
76-
77-
observer.observe( checkoutBlock, {
78-
childList: true,
79-
subtree: true,
80-
} );
61+
callWhenElementIsAvailable( selector, updateTokenLabels );
8162
}
8263
}

client/blocks/upe/upe-deferred-intent-creation/payment-elements.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const PaymentElements = ( { api, ...props } ) => {
5454
* @param {string} paymentMethodId
5555
* @param {Array} upeMethods
5656
* @param {WCStripeAPI} api
57+
* @param {string} description
5758
* @param {string} testingInstructions
5859
* @param {boolean} showSaveOption
5960
*
@@ -63,6 +64,7 @@ export const getDeferredIntentCreationUPEFields = (
6364
paymentMethodId,
6465
upeMethods,
6566
api,
67+
description,
6668
testingInstructions,
6769
showSaveOption
6870
) => {
@@ -71,6 +73,7 @@ export const getDeferredIntentCreationUPEFields = (
7173
paymentMethodId={ paymentMethodId }
7274
upeMethods={ upeMethods }
7375
api={ api }
76+
description={ description }
7477
testingInstructions={ testingInstructions }
7578
showSaveOption={ showSaveOption }
7679
/>

client/blocks/upe/upe-deferred-intent-creation/payment-processor.js

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import {
2020
} from '../hooks';
2121
import { getBlocksConfiguration } from 'wcstripe/blocks/utils';
2222
import WCStripeAPI from 'wcstripe/api';
23+
import {
24+
maybeShowCashAppLimitNotice,
25+
removeCashAppLimitNotice,
26+
} from 'wcstripe/stripe-utils/cash-app-limit-notice-handler';
2327

2428
/**
2529
* Gets the Stripe element options.
@@ -72,6 +76,7 @@ export function validateElements( elements ) {
7276
* @param {*} args Additional arguments passed for payment processing on the Block Checkout.
7377
* @param {WCStripeAPI} args.api The Stripe API object.
7478
* @param {string} args.activePaymentMethod The currently selected/active payment method ID.
79+
* @param {string} args.description The payment method description to display.
7580
* @param {string} args.testingInstructions The testing instructions to display.
7681
* @param {Object} args.eventRegistration The checkout event emitter registration object.
7782
* @param {Object} args.emitResponse Various helpers for usage with observer response objects.
@@ -87,6 +92,7 @@ export function validateElements( elements ) {
8792
const PaymentProcessor = ( {
8893
api,
8994
activePaymentMethod,
95+
description,
9096
testingInstructions,
9197
eventRegistration: { onPaymentSetup, onCheckoutSuccess, onCheckoutFail },
9298
emitResponse,
@@ -99,6 +105,10 @@ const PaymentProcessor = ( {
99105
} ) => {
100106
const stripe = useStripe();
101107
const elements = useElements();
108+
const [
109+
selectedPaymentMethodType,
110+
setSelectedPaymentMethodType,
111+
] = useState( null );
102112
const [ isPaymentElementComplete, setIsPaymentElementComplete ] = useState(
103113
false
104114
);
@@ -228,6 +238,19 @@ const PaymentProcessor = ( {
228238
]
229239
);
230240

241+
// Show the Cash App limit notice if the payment method is selected and the cart amount is higher than 2000 USD.
242+
useEffect( () => {
243+
if ( selectedPaymentMethodType === 'cashapp' ) {
244+
maybeShowCashAppLimitNotice(
245+
'.wc-block-checkout__payment-method .wc-block-components-notices',
246+
Number( getBlocksConfiguration()?.cartTotal ),
247+
true
248+
);
249+
} else {
250+
removeCashAppLimitNotice();
251+
}
252+
}, [ selectedPaymentMethodType ] );
253+
231254
usePaymentCompleteHandler(
232255
api,
233256
stripe,
@@ -247,12 +270,19 @@ const PaymentProcessor = ( {
247270

248271
useStripeLink( api, elements, paymentMethodsConfig );
249272

250-
const updatePaymentElementCompletionStatus = ( event ) => {
251-
setIsPaymentElementComplete( event.complete );
273+
const onSelectedPaymentMethodChange = ( { value, complete } ) => {
274+
setSelectedPaymentMethodType( value.type );
275+
setIsPaymentElementComplete( complete );
252276
};
253277

254278
return (
255279
<>
280+
<p
281+
className="content"
282+
dangerouslySetInnerHTML={ {
283+
__html: description,
284+
} }
285+
/>
256286
<p
257287
className="content"
258288
dangerouslySetInnerHTML={ {
@@ -261,7 +291,7 @@ const PaymentProcessor = ( {
261291
/>
262292
<PaymentElement
263293
options={ getStripeElementOptions() }
264-
onChange={ updatePaymentElementCompletionStatus }
294+
onChange={ onSelectedPaymentMethodChange }
265295
className="wcstripe-payment-element"
266296
/>
267297
</>

client/classic/upe/deferred-intent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ jQuery( function ( $ ) {
133133
}
134134
}
135135

136-
// On every page load and on hash change, check to see whether we should display the Voucher (Boleto/Oxxo) or Wallet (CashApp/WeChat Pay) modal.
136+
// On every page load and on hash change, check to see whether we should display the Voucher (Boleto/Oxxo/Multibanco) or Wallet (CashApp/WeChat Pay) modal.
137137
// Every page load is needed for the Pay for Order page which doesn't trigger the hash change.
138138
maybeConfirmVoucherOrWalletPayment();
139139
$( window ).on( 'hashchange', () => {

client/classic/upe/index.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { getStripeServerData, getUPETerms } from '../../stripe-utils';
44
import { legacyHashchangeHandler } from './legacy-support';
55
import './style.scss';
66
import './deferred-intent.js';
7+
import {
8+
maybeShowCashAppLimitNotice,
9+
removeCashAppLimitNotice,
10+
} from 'wcstripe/stripe-utils/cash-app-limit-notice-handler';
711

812
jQuery( function ( $ ) {
913
const key = getStripeServerData()?.key;
@@ -190,7 +194,11 @@ jQuery( function ( $ ) {
190194
if ( error ) {
191195
const upeType = formFields.wc_stripe_selected_upe_payment_type;
192196

193-
if ( upeType !== 'boleto' && upeType !== 'oxxo' ) {
197+
if (
198+
upeType !== 'boleto' &&
199+
upeType !== 'oxxo' &&
200+
upeType !== 'multibanco'
201+
) {
194202
await api.updateFailedOrder(
195203
paymentIntentId,
196204
response.order_id
@@ -274,14 +282,26 @@ jQuery( function ( $ ) {
274282
}
275283

276284
// Handle the checkout form when WooCommerce Gateway Stripe is chosen.
277-
$( 'form.checkout' ).on( 'checkout_place_order_stripe', function () {
278-
if ( ! isUsingSavedPaymentMethod() ) {
279-
if ( isUPEEnabled && paymentIntentId ) {
280-
handleUPECheckout( $( this ) );
281-
return false;
285+
$( 'form.checkout' )
286+
.on( 'checkout_place_order_stripe', function () {
287+
if ( ! isUsingSavedPaymentMethod() ) {
288+
if ( isUPEEnabled && paymentIntentId ) {
289+
handleUPECheckout( $( this ) );
290+
return false;
291+
}
282292
}
283-
}
284-
} );
293+
} )
294+
.on( 'change', '.wc_payment_methods', () => {
295+
// Check to see whether we should display the Cash App limit notice.
296+
if ( $( 'input#payment_method_stripe_cashapp' ).is( ':checked' ) ) {
297+
maybeShowCashAppLimitNotice(
298+
'.woocommerce-checkout-payment',
299+
Number( getStripeServerData()?.cartTotal )
300+
);
301+
} else {
302+
removeCashAppLimitNotice();
303+
}
304+
} );
285305

286306
// Add terms parameter to UPE if save payment information checkbox is checked.
287307
// This shows required legal mandates when customer elects to save payment method during checkout.

client/classic/upe/payment-processing.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ export const createAndConfirmSetupIntent = (
304304
};
305305

306306
/**
307-
* Handles displaying the Boleto or Oxxo voucher to the customer and then redirecting
307+
* Handles displaying the Boleto or Oxxo or Multibanco voucher to the customer and then redirecting
308308
* them to the order received page once they close the voucher window.
309309
*
310310
* When processing a payment for one of our voucher payment methods on the checkout or order pay page,
@@ -361,6 +361,10 @@ export const confirmVoucherPayment = async ( api, jQueryForm ) => {
361361
confirmPayment = await api
362362
.getStripe()
363363
.confirmBoletoPayment( clientSecret, {} );
364+
} else if ( paymentMethodType === 'multibanco' ) {
365+
confirmPayment = await api
366+
.getStripe()
367+
.confirmMultibancoPayment( clientSecret, {} );
364368
} else {
365369
confirmPayment = await api
366370
.getStripe()

0 commit comments

Comments
 (0)