Skip to content
This repository was archived by the owner on Feb 23, 2024. It is now read-only.

Commit 55b5335

Browse files
mikejolleynerrad
andauthored
Update Stripe/payment payment notices (#2417)
* Update notices to say `card` instead of `card's` * Track isEmpty per field so placeholders are not visible when focusing and defocusing other fields * Make payment notices non-dissmissable, and removed on payment method switch * Don't add validation notices * implement nullish coalescing operator Co-authored-by: Darren Ethier <[email protected]>
1 parent 72adf29 commit 55b5335

File tree

6 files changed

+62
-38
lines changed

6 files changed

+62
-38
lines changed

assets/js/base/components/payment-methods/payment-methods.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import {
55
usePaymentMethods,
66
usePaymentMethodInterface,
7+
useStoreNotices,
8+
useEmitResponse,
79
} from '@woocommerce/base-hooks';
810
import {
911
useCallback,
@@ -63,6 +65,8 @@ const PaymentMethods = () => {
6365
} = usePaymentMethodInterface();
6466
const currentPaymentMethodInterface = useRef( paymentMethodInterface );
6567
const [ selectedToken, setSelectedToken ] = useState( 0 );
68+
const { noticeContexts } = useEmitResponse();
69+
const { removeNotice } = useStoreNotices();
6670

6771
// update ref on change.
6872
useEffect( () => {
@@ -98,7 +102,10 @@ const PaymentMethods = () => {
98102
const renderedTabs = (
99103
<Tabs
100104
className="wc-block-components-checkout-payment-methods"
101-
onSelect={ ( tabName ) => setActivePaymentMethod( tabName ) }
105+
onSelect={ ( tabName ) => {
106+
setActivePaymentMethod( tabName );
107+
removeNotice( 'wc-payment-error', noticeContexts.PAYMENTS );
108+
} }
102109
tabs={ Object.keys( currentPaymentMethods.current ).map(
103110
( name ) => {
104111
const { label, ariaLabel } = currentPaymentMethods.current[

assets/js/base/context/cart-checkout/payment-methods/payment-method-data-context.js

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -290,22 +290,30 @@ export const PaymentMethodDataProvider = ( { children } ) => {
290290
response?.meta?.shippingData
291291
);
292292
} else if ( isFailResponse( response ) ) {
293-
addErrorNotice( response?.message, {
294-
id: 'wc-payment-error',
295-
context:
296-
response?.messageContext || noticeContexts.PAYMENTS,
297-
} );
293+
if ( response.message && response.message.length ) {
294+
addErrorNotice( response.message, {
295+
id: 'wc-payment-error',
296+
isDismissible: false,
297+
context:
298+
response?.messageContext ||
299+
noticeContexts.PAYMENTS,
300+
} );
301+
}
298302
setPaymentStatus().failed(
299303
response?.message,
300304
response?.meta?.paymentMethodData,
301305
response?.meta?.billingData
302306
);
303307
} else if ( isErrorResponse( response ) ) {
304-
addErrorNotice( response?.message, {
305-
id: 'wc-payment-error',
306-
context:
307-
response?.messageContext || noticeContexts.PAYMENTS,
308-
} );
308+
if ( response.message && response.message.length ) {
309+
addErrorNotice( response.message, {
310+
id: 'wc-payment-error',
311+
isDismissible: false,
312+
context:
313+
response?.messageContext ||
314+
noticeContexts.PAYMENTS,
315+
} );
316+
}
309317
setPaymentStatus().error( response.message );
310318
setValidationErrors( response?.validationErrors );
311319
} else {

assets/js/payment-method-extensions/payment-methods/stripe/credit-card/elements.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ export const CardElements = ( {
6767
onChange,
6868
inputErrorComponent: ValidationInputError,
6969
} ) => {
70-
const [ isEmpty, setIsEmpty ] = useState( true );
70+
const [ isEmpty, setIsEmpty ] = useState( {
71+
cardNumber: true,
72+
cardExpiry: true,
73+
cardCvc: true,
74+
} );
7175
const {
7276
options: cardNumOptions,
7377
onActive: cardNumOnActive,
@@ -86,25 +90,25 @@ export const CardElements = ( {
8690
error: cardCvcError,
8791
setError: cardCvcSetError,
8892
} = useElementOptions();
89-
const errorCallback = ( errorSetter ) => ( event ) => {
93+
const errorCallback = ( errorSetter, elementId ) => ( event ) => {
9094
if ( event.error ) {
9195
errorSetter( event.error.message );
9296
} else {
9397
errorSetter( '' );
9498
}
95-
setIsEmpty( event.empty );
99+
setIsEmpty( { ...isEmpty, [ elementId ]: event.empty } );
96100
onChange( event );
97101
};
98102
return (
99103
<div className="wc-block-card-elements">
100104
<div className="wc-block-gateway-container wc-card-number-element">
101105
<CardNumberElement
102-
onChange={ errorCallback( cardNumSetError ) }
106+
onChange={ errorCallback( cardNumSetError, 'cardNumber' ) }
103107
options={ cardNumOptions }
104108
className={ baseTextInputStyles }
105109
id="wc-stripe-card-number-element"
106-
onFocus={ () => cardNumOnActive( isEmpty ) }
107-
onBlur={ () => cardNumOnActive( isEmpty ) }
110+
onFocus={ () => cardNumOnActive( isEmpty.cardNumber ) }
111+
onBlur={ () => cardNumOnActive( isEmpty.cardNumber ) }
108112
/>
109113
<label htmlFor="wc-stripe-card-number-element">
110114
{ __( 'Card Number', 'woo-gutenberg-product-blocks' ) }
@@ -113,11 +117,14 @@ export const CardElements = ( {
113117
</div>
114118
<div className="wc-block-gateway-container wc-card-expiry-element">
115119
<CardExpiryElement
116-
onChange={ errorCallback( cardExpirySetError ) }
120+
onChange={ errorCallback(
121+
cardExpirySetError,
122+
'cardExpiry'
123+
) }
117124
options={ cardExpiryOptions }
118125
className={ baseTextInputStyles }
119-
onFocus={ () => cardExpiryOnActive( isEmpty ) }
120-
onBlur={ () => cardExpiryOnActive( isEmpty ) }
126+
onFocus={ () => cardExpiryOnActive( isEmpty.cardExpiry ) }
127+
onBlur={ () => cardExpiryOnActive( isEmpty.cardExpiry ) }
121128
id="wc-stripe-card-expiry-element"
122129
/>
123130
<label htmlFor="wc-stripe-card-expiry-element">
@@ -127,11 +134,11 @@ export const CardElements = ( {
127134
</div>
128135
<div className="wc-block-gateway-container wc-card-cvc-element">
129136
<CardCvcElement
130-
onChange={ errorCallback( cardCvcSetError ) }
137+
onChange={ errorCallback( cardCvcSetError, 'cardCvc' ) }
131138
options={ cardCvcOptions }
132139
className={ baseTextInputStyles }
133-
onFocus={ () => cardCvcOnActive( isEmpty ) }
134-
onBlur={ () => cardCvcOnActive( isEmpty ) }
140+
onFocus={ () => cardCvcOnActive( isEmpty.cardCvc ) }
141+
onBlur={ () => cardCvcOnActive( isEmpty.cardCvc ) }
135142
id="wc-stripe-card-code-element"
136143
/>
137144
<label htmlFor="wc-stripe-card-code-element">

assets/js/payment-method-extensions/payment-methods/stripe/credit-card/use-checkout-subscriptions.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ export const useCheckoutSubscriptions = (
6161
onStripeError.current = ( event ) => {
6262
const type = event.error.type;
6363
const code = event.error.code || '';
64-
let message = getErrorMessageForTypeAndCode( type, code );
65-
message = message || event.error.message;
64+
const message =
65+
getErrorMessageForTypeAndCode( type, code ) ??
66+
event.error.message;
6667
setError( error );
6768
return message;
6869
};

assets/js/payment-method-extensions/payment-methods/stripe/stripe-utils/type-defs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@
7474
* @property {string} country Two-letter ISO code for
7575
* the country on the card.
7676
* @property {number} exp_month Two-digit number for
77-
* card's expiry month.
77+
* card expiry month.
7878
* @property {number} exp_year Two-digit number for
79-
* card's expiry year.
79+
* card expiry year.
8080
* @property {string} fingerprint Uniquely identifies this
8181
* particular card number
8282
* @property {string} funding The card funding type

assets/js/payment-method-extensions/payment-methods/stripe/stripe-utils/utils.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,15 @@ const getErrorMessageForCode = ( code ) => {
174174
'woocommerce-gateway-stripe'
175175
),
176176
[ errorCodes.INVALID_EXPIRY_MONTH ]: __(
177-
"The card's expiration month is invalid.",
177+
'The card expiration month is invalid.',
178178
'woocommerce-gateway-stripe'
179179
),
180180
[ errorCodes.INVALID_EXPIRY_YEAR ]: __(
181-
"The card's expiration year is invalid.",
181+
'The card expiration year is invalid.',
182182
'woocommerce-gateway-stripe'
183183
),
184184
[ errorCodes.INVALID_CVC ]: __(
185-
"The card's security code is invalid.",
185+
'The card security code is invalid.',
186186
'woocommerce-gateway-stripe'
187187
),
188188
[ errorCodes.INCORRECT_NUMBER ]: __(
@@ -194,27 +194,27 @@ const getErrorMessageForCode = ( code ) => {
194194
'woocommerce-gateway-stripe'
195195
),
196196
[ errorCodes.INCOMPLETE_CVC ]: __(
197-
"The card's security code is incomplete.",
197+
'The card security code is incomplete.',
198198
'woocommerce-gateway-stripe'
199199
),
200200
[ errorCodes.INCOMPLETE_EXPIRY ]: __(
201-
"The card's expiration date is incomplete.",
201+
'The card expiration date is incomplete.',
202202
'woocommerce-gateway-stripe'
203203
),
204204
[ errorCodes.EXPIRED_CARD ]: __(
205205
'The card has expired.',
206206
'woocommerce-gateway-stripe'
207207
),
208208
[ errorCodes.INCORRECT_CVC ]: __(
209-
"The card's security code is incorrect.",
209+
'The card security code is incorrect.',
210210
'woocommerce-gateway-stripe'
211211
),
212212
[ errorCodes.INCORRECT_ZIP ]: __(
213-
"The card's zip code failed validation.",
213+
'The card zip code failed validation.',
214214
'woocommerce-gateway-stripe'
215215
),
216216
[ errorCodes.INVALID_EXPIRY_YEAR_PAST ]: __(
217-
"The card's expiration year is in the past",
217+
'The card expiration year is in the past',
218218
'woocommerce-gateway-stripe'
219219
),
220220
[ errorCodes.CARD_DECLINED ]: __(
@@ -230,7 +230,7 @@ const getErrorMessageForCode = ( code ) => {
230230
'woocommerce-gateway-stripe'
231231
),
232232
};
233-
return messages[ code ] || '';
233+
return messages[ code ] || null;
234234
};
235235

236236
const getErrorMessageForTypeAndCode = ( type, code = '' ) => {
@@ -246,10 +246,11 @@ const getErrorMessageForTypeAndCode = ( type, code = '' ) => {
246246
'woo-gutenberg-product-blocks'
247247
);
248248
case errorTypes.CARD_ERROR:
249-
case errorTypes.VALIDATION_ERROR:
250249
return getErrorMessageForCode( code );
250+
case errorTypes.VALIDATION_ERROR:
251+
return ''; // These are shown inline.
251252
}
252-
return '';
253+
return null;
253254
};
254255

255256
export {

0 commit comments

Comments
 (0)