Skip to content

Commit 21f8822

Browse files
committed
Merge remote-tracking branch 'origin/release/8.6.1' into trunk
2 parents 8895dfd + 12c464f commit 21f8822

File tree

96 files changed

+2902
-1362
lines changed

Some content is hidden

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

96 files changed

+2902
-1362
lines changed

bin/docker-setup.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ redirect_output() {
1818
# https://hub.docker.com/_/wordpress#running-as-an-arbitrary-user
1919
cli()
2020
{
21-
redirect_output docker run -it --env-file default.env --rm --user xfs --volumes-from $WP_CONTAINER --network container:$WP_CONTAINER wordpress:cli "$@"
21+
redirect_output docker run -it --env-file default.env --rm --volumes-from $WP_CONTAINER --network container:$WP_CONTAINER wordpress:cli "$@"
2222
}
2323

2424
set +e
@@ -100,6 +100,7 @@ cli wp option set woocommerce_store_postcode "94110"
100100
cli wp option set woocommerce_currency "USD"
101101
cli wp option set woocommerce_product_type "both"
102102
cli wp option set woocommerce_allow_tracking "no"
103+
cli wp option set woocommerce_coming_soon "no"
103104

104105
echo "Importing WooCommerce shop pages..."
105106
cli wp wc --user=admin tool run install_pages

changelog.txt

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

3+
= 8.6.1 - 2024-08-09 =
4+
* Tweak - Improves the wording of the invalid Stripe keys errors, instructing merchants to click the "Configure connection" button instead of manually setting the keys.
5+
* Add - Includes a new promotional surface to encourage merchants to re-connect their Stripe account using the new flow.
6+
* Add - Added filter to enable updating Level 3 data based on order data.
7+
* Add - Replace account key sharing and replace it with an OAuth connect flow allowing users to connect their Stripe account automatically without the need to find keys.
8+
* Add - Indicate the activation status of each payment method individually, instead of using a general notice.
9+
* Fix - JS error when billing country field does not exist on the payment method page.
10+
* Fix - Prevent multiple instances of the "Update the Payment Method" checkbox from displaying on the My Account > Payment Methods page when using the legacy checkout experience.
11+
* Fix - Prevent duplicate customer creation during guest checkout.
12+
* Fix - Hiding Multibanco payment method when the Stripe account country is not supported.
13+
* Fix - Display the payment decline reason on the checkout when using Cash App or WeChat.
14+
* Fix - Re-enable the "Place order" button on the block checkout after closing the WeChat or Cash App payment modal.
15+
* Fix - When SEPA tokens are added via the My Account > Payment methods page, ensure they are attached to the Stripe customer.
16+
* Fix - Clear the saved Stripe Link payment methods when a customer cache is cleared to ensure cached methods are updated promptly.
17+
* Fix - Display Stripe Link payment methods correctly in both Block Checkout and My Account pages.
18+
* Fix - Resolve an error when adding a saved card payment method in My Account when Stripe Link is enabled.
19+
* Fix - Resolved an error when using 3D Secure-enabled cards with Stripe Link enabled.
20+
* Fix - Corrected setup intent payment method types to include 'link' when Stripe Link is enabled, resolving errors during subscription signups.
21+
* Fix - Resolved an issue where changing the payment method for subscriptions failed after 3D-Secure authentication.
22+
* Fix - Prevent displaying the default admin description on the checkout page when a payment method description is empty.
23+
* Fix - Adds back the ability to perform direct refunds for giropay orders via the order details page.
24+
* Fix - After configuring webhooks automatically ensure only the latest webhook endpoint is active, deleting duplicates configured manually.
25+
* Fix - Resolved PHP errors related to detaching payment methods after failed 3D-Secure challenges.
26+
* Tweak - Minor text updates to webhook-related configuration labels and buttons.
27+
* Tweak - Improve UX by using the 3DS verification modal to confirm setup intents for subscription sign-ups, ensuring customers stay on the checkout page.
28+
* Tweak - Display a notice when the Stripe connect URL is not available.
29+
* Fix - Prevent adding multiple copies of the same order notes.
30+
* Tweak - Automatically configure webhooks after completing the OAuth Stripe flow.
31+
* Tweak - Don't process webhooks when the webhook secret isn't set in the store.
32+
333
= 8.5.2 - 2024-07-22 =
434
* Fix - Fixed errors when using Link to purchase subscription products that could lead to duplicate payment attempts.
535
* Fix - Prevent failures creating SetupIntents when using a non-saved payment method on the Legacy checkout experience.
@@ -26,6 +56,8 @@
2656
* Fix - Ensure subscriptions purchased with iDEAL or Bancontact are correctly set to SEPA debit prior to processing the intitial payment.
2757
* Tweak - Stripe API version updated to support 2024-06-20.
2858
* 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.
59+
* Tweak - Limit the configure webhooks button to 1 click per minute to prevent multiple webhook creations.
60+
* Fix - Address Klarna currency rules to ensure correct presentment and availability based on merchant and customer locations.
2961
* Fix - Prevent saved SEPA Sources from being displayed as available payment methods when the Updated checkout experience is enabled.
3062

3163
= 8.4.0 - 2024-06-13 =

client/api/index.js

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,10 @@ export default class WCStripeAPI {
225225

226226
// Card Payments.
227227
return this.getStripe()
228-
.confirmCardSetup( response.data.client_secret )
228+
.confirmSetup( {
229+
clientSecret: response.data.client_secret,
230+
redirect: 'if_required',
231+
} )
229232
.then( ( confirmedSetupIntent ) => {
230233
const { setupIntent, error } = confirmedSetupIntent;
231234
if ( error ) {
@@ -307,6 +310,10 @@ export default class WCStripeAPI {
307310

308311
const orderPayIndex = redirectUrl.indexOf( 'order-pay' );
309312
const isOrderPage = orderPayIndex > -1;
313+
const isChangingPayment =
314+
isOrderPage &&
315+
document.querySelectorAll( '#wc-stripe-change-payment-method' )
316+
.length > 0;
310317

311318
// If we're on the Pay for Order page, get the order ID
312319
// directly from the URL instead of relying on the hash.
@@ -325,9 +332,19 @@ export default class WCStripeAPI {
325332
orderId = orderIdPartials[ 0 ];
326333
}
327334

335+
// After processing the intent, trigger the appropriate AJAX action.
336+
const ajaxAction = isChangingPayment
337+
? 'confirm_change_payment'
338+
: 'update_order_status';
339+
340+
const confirmArgs = {
341+
clientSecret,
342+
redirect: 'if_required',
343+
};
344+
328345
const confirmAction = isSetupIntent
329-
? this.getStripe().confirmCardSetup( clientSecret )
330-
: this.getStripe( true ).confirmCardPayment( clientSecret );
346+
? this.getStripe().confirmSetup( confirmArgs )
347+
: this.getStripe( true ).confirmPayment( confirmArgs );
331348

332349
const request = confirmAction
333350
// ToDo: Switch to an async function once it works with webpack.
@@ -341,17 +358,14 @@ export default class WCStripeAPI {
341358
( result.error.setup_intent &&
342359
result.error.setup_intent.id );
343360

344-
const ajaxCall = this.request(
345-
this.getAjaxUrl( 'update_order_status' ),
346-
{
347-
order_id: orderId,
348-
// Update the current order status nonce with the new one to ensure that the update
349-
// order status call works when a guest user creates an account during checkout.
350-
intent_id: intentId,
351-
payment_method_id: paymentMethodToSave || null,
352-
_ajax_nonce: nonce,
353-
}
354-
);
361+
const ajaxCall = this.request( this.getAjaxUrl( ajaxAction ), {
362+
order_id: orderId,
363+
// Update the current order status nonce with the new one to ensure that the update
364+
// order status call works when a guest user creates an account during checkout.
365+
intent_id: intentId,
366+
payment_method_id: paymentMethodToSave || null,
367+
_ajax_nonce: nonce,
368+
} );
355369

356370
return [ ajaxCall, result.error ];
357371
} )
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { __ } from '@wordpress/i18n';
2+
import classNames from 'classnames';
3+
import mark from './mark.svg';
4+
5+
/**
6+
* StripeMark component.
7+
*
8+
* @param {Object} props The component props.
9+
* @param {string} [props.className] Additional classes to add to the StripeMark component.
10+
* @param {any} props.restProps Additional props to add to the StripeMark component.
11+
*
12+
* @return {JSX.Element} The rendered StripeMark component.
13+
*/
14+
const StripeMark = ( { className, ...restProps } ) => (
15+
<img
16+
className={ classNames( 'woocommerce-stripe-mark-logo', className ) }
17+
src={ mark }
18+
width="64"
19+
height="64"
20+
alt={ __( 'Stripe logo', 'woocommerce-gateway-stripe' ) }
21+
{ ...restProps }
22+
/>
23+
);
24+
25+
export default StripeMark;
Lines changed: 1 addition & 0 deletions
Loading

client/brand-logos/woo-white/index.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { __ } from '@wordpress/i18n';
2+
import classNames from 'classnames';
3+
import logo from './logo.svg';
4+
5+
/**
6+
* WooLogo component.
7+
*
8+
* @param {Object} props The component props.
9+
* @param {string} [props.className] Additional classes to add to the WooLogo component.
10+
* @param {any} props.restProps Additional props to add to the WooLogo component.
11+
*
12+
* @return {JSX.Element} The rendered WooLogo component.
13+
*/
14+
const WooLogo = ( { className, ...restProps } ) => (
15+
<img
16+
className={ classNames(
17+
'woocommerce-stripe-woo-white-logo',
18+
className
19+
) }
20+
src={ logo }
21+
width="64"
22+
height="64"
23+
alt={ __( 'Woo logo', 'woocommerce-gateway-stripe' ) }
24+
{ ...restProps }
25+
/>
26+
);
27+
28+
export default WooLogo;

client/brand-logos/woo-white/logo.svg

Lines changed: 3 additions & 0 deletions
Loading

client/classic/upe/payment-processing.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {
66
getUpeSettings,
77
showErrorCheckout,
88
appendSetupIntentToForm,
9+
unblockBlockCheckout,
10+
resetBlockCheckoutPaymentState,
911
} from '../../stripe-utils';
1012
import { getFontRulesFromPage } from '../../styles/upe';
1113

@@ -467,6 +469,12 @@ export const confirmWalletPayment = async ( api, jQueryForm ) => {
467469
throw confirmPayment.error;
468470
}
469471

472+
if ( confirmPayment.paymentIntent.last_payment_error ) {
473+
throw new Error(
474+
confirmPayment.paymentIntent.last_payment_error.message
475+
);
476+
}
477+
470478
// Do not redirect to the order received page if the modal is closed without payment.
471479
// Otherwise redirect to the order received page.
472480
if ( confirmPayment.paymentIntent.status !== 'requires_action' ) {
@@ -476,5 +484,7 @@ export const confirmWalletPayment = async ( api, jQueryForm ) => {
476484
showErrorCheckout( error.message );
477485
} finally {
478486
jQueryForm.removeClass( 'processing' ).unblock();
487+
unblockBlockCheckout();
488+
resetBlockCheckoutPaymentState();
479489
}
480490
};

client/components/chip/index.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import React from 'react';
2+
import classNames from 'classnames';
3+
import './styles.scss';
4+
5+
/**
6+
* The Chip component.
7+
*
8+
* The Chip component is used to display a small piece of information in a colored chip.
9+
* It implements the 'Chip' element described in the WooCommerce Design Library.
10+
*
11+
* @param {Object} props The component props.
12+
* @param {string} props.text The text of the chip.
13+
* @param {string} props.color The color of the chip. Can be 'gray', 'green', 'blue', 'red', 'yellow'.
14+
* @param {JSX.Element} props.icon Optional icon for the chip.
15+
* @param {string} props.iconPosition The position of the icon. Default is 'right'. Can be 'left' or 'right'.
16+
*
17+
* @return {JSX.Element} The rendered Chip component.
18+
*/
19+
const Chip = ( { text, color = 'gray', icon, iconPosition = 'right' } ) => {
20+
return (
21+
<span
22+
className={ classNames(
23+
'wcstripe-chip',
24+
`wc-stripe-chip-${ color }`
25+
) }
26+
>
27+
{ iconPosition === 'left' && icon && <>{ icon }</> }
28+
{ text }
29+
{ iconPosition === 'right' && icon && <>{ icon }</> }
30+
</span>
31+
);
32+
};
33+
34+
export default Chip;

client/components/chip/styles.scss

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
@import '../../styles/abstracts/styles.scss';
2+
3+
.wcstripe-chip {
4+
font-size: 12px;
5+
display: inline-flex;
6+
align-items: center;
7+
justify-content: center;
8+
font-weight: 400;
9+
padding: 0.25rem 0.5rem;
10+
border-radius: 0.2rem;
11+
line-height: 16px;
12+
white-space: nowrap;
13+
flex-direction: row;
14+
gap: 2px;
15+
16+
&.wc-stripe-chip-gray {
17+
background: $wp-gray-0;
18+
color: $wp-gray-80;
19+
svg {
20+
fill: $wp-gray-80;
21+
}
22+
}
23+
&.wc-stripe-chip-green {
24+
background: $wp-green-0;
25+
color: $wp-green-70;
26+
svg {
27+
fill: $wp-green-70;
28+
}
29+
}
30+
&.wc-stripe-chip-blue {
31+
background: $wp-blue-0;
32+
color: $wp-blue-70;
33+
svg {
34+
fill: $wp-blue-70;
35+
}
36+
}
37+
&.wc-stripe-chip-red {
38+
background: $wp-red-0;
39+
color: $wp-red-70;
40+
svg {
41+
fill: $wp-red-70;
42+
}
43+
}
44+
&.wc-stripe-chip-yellow {
45+
background: $wp-yellow-0;
46+
color: $wp-yellow-70;
47+
svg {
48+
fill: $wp-yellow-70;
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)