Skip to content

Commit 71f1d92

Browse files
authored
Fix missing payment method logos (JCB, CUP, CB) in checkout (#11101)
1 parent 8d4c8cc commit 71f1d92

File tree

5 files changed

+174
-36
lines changed

5 files changed

+174
-36
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: fix
3+
4+
Fix missing payment method logos (JCB, CUP, CB) in checkout.

client/checkout/blocks/payment-method-label.js

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,13 @@
22
* Internal dependencies
33
*/
44
import { PaymentMethodsLogos } from './payment-methods-logos';
5-
import Visa from 'assets/images/payment-method-icons/visa.svg?asset';
6-
import Mastercard from 'assets/images/payment-method-icons/mastercard.svg?asset';
7-
import Amex from 'assets/images/payment-method-icons/amex.svg?asset';
8-
import Discover from 'assets/images/payment-method-icons/discover.svg?asset';
5+
import { getCardBrands } from 'wcpay/utils/card-brands';
96
import { useStripeForUPE } from 'wcpay/hooks/use-stripe-async';
107
import { getUPEConfig } from 'wcpay/utils/checkout';
118
import { __ } from '@wordpress/i18n';
129
import './style.scss';
1310
import { useEffect, useState, useRef } from '@wordpress/element';
1411
import { getAppearance } from 'wcpay/checkout/upe-styles';
15-
16-
const paymentMethods = [
17-
{
18-
name: 'visa',
19-
component: Visa,
20-
},
21-
{
22-
name: 'mastercard',
23-
component: Mastercard,
24-
},
25-
{
26-
name: 'amex',
27-
component: Amex,
28-
},
29-
{
30-
name: 'discover',
31-
component: Discover,
32-
},
33-
// TODO: Missing Diners Club
34-
// TODO: What other card payment methods should be here?
35-
];
3612
const breakpointConfigs = [
3713
{ breakpoint: 550, maxElements: 2 },
3814
{ breakpoint: 330, maxElements: 1 },
@@ -90,7 +66,7 @@ export default ( { api, title, iconLight, iconDark, upeName } ) => {
9066
{ upeName === 'card' ? (
9167
<PaymentMethodsLogos
9268
maxElements={ 4 }
93-
paymentMethods={ paymentMethods }
69+
paymentMethods={ getCardBrands() }
9470
breakpointConfigs={ breakpointConfigs }
9571
/>
9672
) : (

client/checkout/classic/event-handlers.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ import { isPreviewing } from 'wcpay/checkout/preview';
3232
import { recordUserEvent } from 'tracks';
3333
import '../utils/copy-test-number';
3434
import { SHORTCODE_BILLING_ADDRESS_FIELDS } from '../constants';
35-
import Visa from 'assets/images/payment-method-icons/visa.svg?asset';
36-
import Mastercard from 'assets/images/payment-method-icons/mastercard.svg?asset';
37-
import Amex from 'assets/images/payment-method-icons/amex.svg?asset';
38-
import Discover from 'assets/images/payment-method-icons/discover.svg?asset';
35+
import { getCardBrands } from 'wcpay/utils/card-brands';
3936

4037
jQuery( function ( $ ) {
4138
enqueueFraudScripts( getUPEConfig( 'fraudServices' ) );
@@ -181,12 +178,7 @@ jQuery( function ( $ ) {
181178
innerContainer.setAttribute( 'tabindex', '0' );
182179
innerContainer.setAttribute( 'data-testid', 'payment-methods-logos' );
183180

184-
const paymentMethods = [
185-
{ name: 'visa', component: Visa },
186-
{ name: 'mastercard', component: Mastercard },
187-
{ name: 'amex', component: Amex },
188-
{ name: 'discover', component: Discover },
189-
];
181+
const paymentMethods = getCardBrands();
190182

191183
function getMaxElements() {
192184
const paymentMethodElement = document.querySelector(
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* Jest environment configuration
3+
*/
4+
5+
/**
6+
* Internal dependencies
7+
*/
8+
import { getCardBrands } from '../card-brands';
9+
import { getUPEConfig } from 'wcpay/utils/checkout';
10+
11+
// Mock the getUPEConfig function
12+
jest.mock( 'wcpay/utils/checkout', () => ( {
13+
getUPEConfig: jest.fn(),
14+
} ) );
15+
16+
// Mock the global wcpaySettings will be set in each test
17+
18+
describe( 'getCardBrands', () => {
19+
test( 'returns base brands for non-France merchants', () => {
20+
global.window.wcpaySettings = {
21+
accountStatus: {
22+
country: 'US',
23+
},
24+
};
25+
// Mock getUPEConfig to return null
26+
getUPEConfig.mockReturnValue( null );
27+
28+
const brands = getCardBrands();
29+
30+
// Should include the 4 base brands plus JCB and CUP
31+
expect( brands ).toHaveLength( 6 );
32+
expect( brands.map( ( b ) => b.name ) ).toEqual( [
33+
'visa',
34+
'mastercard',
35+
'amex',
36+
'discover',
37+
'jcb',
38+
'unionpay',
39+
] );
40+
} );
41+
42+
test( 'includes CB for France merchants', () => {
43+
global.window.wcpaySettings = {
44+
accountStatus: {
45+
country: 'FR',
46+
},
47+
};
48+
// Mock getUPEConfig to return France
49+
getUPEConfig.mockReturnValue( 'FR' );
50+
51+
const brands = getCardBrands();
52+
53+
// Should include all brands including CB
54+
expect( brands ).toHaveLength( 7 );
55+
expect( brands.map( ( b ) => b.name ) ).toEqual( [
56+
'visa',
57+
'mastercard',
58+
'amex',
59+
'discover',
60+
'jcb',
61+
'unionpay',
62+
'cartes_bancaires',
63+
] );
64+
} );
65+
66+
test( 'handles missing account status gracefully', () => {
67+
global.window.wcpaySettings = {};
68+
// Mock getUPEConfig to return null
69+
getUPEConfig.mockReturnValue( null );
70+
71+
const brands = getCardBrands();
72+
73+
// Should still return base brands without CB
74+
expect( brands ).toHaveLength( 6 );
75+
expect( brands.map( ( b ) => b.name ) ).not.toContain(
76+
'cartes_bancaires'
77+
);
78+
} );
79+
80+
test( 'handles missing wcpaySettings gracefully', () => {
81+
global.window.wcpaySettings = undefined;
82+
// Mock getUPEConfig to return null
83+
getUPEConfig.mockReturnValue( null );
84+
85+
const brands = getCardBrands();
86+
87+
// Should still return base brands without CB
88+
expect( brands ).toHaveLength( 6 );
89+
expect( brands.map( ( b ) => b.name ) ).not.toContain(
90+
'cartes_bancaires'
91+
);
92+
} );
93+
94+
test( 'uses UPE config storeCountry when wcpaySettings is not available', () => {
95+
global.window.wcpaySettings = undefined;
96+
// Mock getUPEConfig to return France for storeCountry
97+
getUPEConfig.mockImplementation( ( key ) => {
98+
if ( key === 'storeCountry' ) {
99+
return 'FR';
100+
}
101+
return null;
102+
} );
103+
104+
const brands = getCardBrands();
105+
106+
// Check if getUPEConfig was called
107+
expect( getUPEConfig ).toHaveBeenCalledWith( 'storeCountry' );
108+
109+
// Should include CB for France
110+
expect( brands ).toHaveLength( 7 );
111+
expect( brands.map( ( b ) => b.name ) ).toContain( 'cartes_bancaires' );
112+
} );
113+
} );

client/utils/card-brands.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import Visa from 'assets/images/payment-method-icons/visa.svg?asset';
5+
import Mastercard from 'assets/images/payment-method-icons/mastercard.svg?asset';
6+
import Amex from 'assets/images/payment-method-icons/amex.svg?asset';
7+
import Discover from 'assets/images/payment-method-icons/discover.svg?asset';
8+
import Jcb from 'assets/images/payment-method-icons/jcb.svg?asset';
9+
import UnionPay from 'assets/images/cards/unionpay.svg?asset';
10+
import Cartebancaire from 'assets/images/cards/cartes_bancaires.svg?asset';
11+
import { getUPEConfig } from 'wcpay/utils/checkout';
12+
13+
/**
14+
* Card brand object interface
15+
*/
16+
interface CardBrand {
17+
name: string;
18+
component: string;
19+
}
20+
21+
/**
22+
* Get card brands array for payment method logos display.
23+
* Returns standard brands (Visa, MC, Amex, Discover) plus JCB, CUP, and CB (if France).
24+
*
25+
* @return {CardBrand[]} Array of card brand objects with name and component properties
26+
*/
27+
export const getCardBrands = (): CardBrand[] => {
28+
const baseBrands: CardBrand[] = [
29+
{ name: 'visa', component: Visa },
30+
{ name: 'mastercard', component: Mastercard },
31+
{ name: 'amex', component: Amex },
32+
{ name: 'discover', component: Discover },
33+
];
34+
35+
// Always add JCB and CUP
36+
const additionalBrands: CardBrand[] = [
37+
{ name: 'jcb', component: Jcb },
38+
{ name: 'unionpay', component: UnionPay },
39+
];
40+
41+
// Add CB (Cartes Bancaires) only for France merchants
42+
// Try multiple approaches to get the country
43+
const accountCountry = getUPEConfig( 'storeCountry' );
44+
45+
if ( accountCountry === 'FR' ) {
46+
additionalBrands.push( {
47+
name: 'cartes_bancaires',
48+
component: Cartebancaire,
49+
} );
50+
}
51+
52+
return [ ...baseBrands, ...additionalBrands ];
53+
};

0 commit comments

Comments
 (0)