Skip to content

Commit a56d0c5

Browse files
committed
Merge release/10.2.0 into trunk
2 parents c6f26ce + f4c3956 commit a56d0c5

File tree

43 files changed

+3604
-290
lines changed

Some content is hidden

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

43 files changed

+3604
-290
lines changed

.claude/CLAUDE.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# CLAUDE.md - WooCommerce Payments Repository Guide
2+
3+
This file provides context about the WooCommerce Payments repository to help Claude Code assist more effectively.
4+
5+
## Repository Overview
6+
7+
WooCommerce Payments (WCPay) is a WordPress plugin that provides payment processing capabilities for WooCommerce stores. It's a complex project combining PHP backend code with a React-based admin interface.
8+
9+
**Key Info:**
10+
- Plugin Name: WooPayments
11+
- License: GPL-3.0-or-later
12+
- Repository: github:Automattic/woocommerce-payments
13+
14+
**Version & Requirements:**
15+
- See `woocommerce-payments.php` header for current version and WordPress/WooCommerce/PHP requirements
16+
- See `package.json` for Node.js version requirements (engines field)
17+
18+
## Directory Structure
19+
20+
### PHP Code
21+
- **`src/`** - Modern PHP code using PSR-4 autoloading and dependency injection
22+
- Uses a service `Container` for dependency injection
23+
- Preferred location for new PHP code
24+
- **`includes/`** - Legacy PHP codebase organized by feature
25+
- `admin/`, `payment-methods/`, `subscriptions/`, `multi-currency/`, etc.
26+
- Still actively used but prefer `src/` for new code
27+
28+
### Frontend Code
29+
- **`client/`** - React/TypeScript frontend application
30+
- `components/` - Reusable UI components
31+
- `settings/`, `checkout/`, `onboarding/` - Feature areas
32+
- `data/` - Redux state management (@wordpress/data)
33+
- Uses React 18.3 and TypeScript
34+
35+
### Tests
36+
- **`tests/unit/`** - PHP unit tests (PHPUnit)
37+
- **`tests/js/`** - JavaScript test configuration
38+
- **`tests/e2e/`** - End-to-end tests (Playwright)
39+
- JS tests are co-located with source files in `client/**/__tests__/`
40+
41+
### Build & Config
42+
- **`webpack/`** - Modular webpack configuration (shared, production, development, HMR)
43+
- **`tasks/`** - Build and release automation
44+
- **`bin/`** - Helper scripts
45+
- **`docker/`** - Docker development environment
46+
47+
## Technology Stack
48+
49+
**Backend:** PHP, WordPress APIs, WooCommerce hooks, Composer
50+
**Frontend:** React, TypeScript, @wordpress/data (Redux), SCSS
51+
**Build:** Webpack, Babel, PostCSS, @wordpress/scripts
52+
**Testing:** PHPUnit, Jest, Playwright, React Testing Library
53+
**Quality:** ESLint, PHPCS, Psalm, TypeScript, Prettier
54+
55+
*See `composer.json`, `package.json`, and `woocommerce-payments.php` for specific version requirements*
56+
57+
## Common Commands
58+
59+
### Development
60+
```bash
61+
npm install # Install dependencies
62+
npm start # Watch JS changes (alias: npm run watch)
63+
npm run hmr # Hot module replacement server
64+
npm run up # Start Docker environment
65+
npm run dev # Start Docker + watch mode
66+
```
67+
68+
### Testing
69+
70+
**PHP Tests:**
71+
```bash
72+
# Standard approach
73+
npm run test:php # Run all PHP tests in Docker
74+
npm run test:php-watch # Watch mode
75+
npm run test:php-coverage # With coverage
76+
```
77+
78+
**JavaScript Tests:**
79+
```bash
80+
npm run test:js # Run all JS tests
81+
npm run test:watch # Watch mode
82+
npm run test:debug # Debug mode
83+
npm run test:update-snapshots # Update snapshots
84+
```
85+
86+
**E2E Tests:**
87+
```bash
88+
npm run test:e2e # Run E2E tests
89+
npm run test:e2e-ui # UI mode
90+
npm run test:e2e-up # Setup test environment
91+
npm run test:e2e-down # Teardown
92+
```
93+
94+
### Build & Quality
95+
```bash
96+
npm run build:client # Build production JS
97+
npm run build # Build release package
98+
npm run lint # Run all linters
99+
npm run lint:js # ESLint + TypeScript
100+
npm run lint:php # PHPCS
101+
npm run lint:php-fix # Auto-fix PHP issues
102+
npm run format # Format with Prettier
103+
npm run psalm # PHP static analysis
104+
```
105+
106+
### Other
107+
```bash
108+
npm run changelog # Add changelog entry
109+
npm run i18n:pot # Generate translations
110+
```
111+
112+
## Development Workflows
113+
114+
### Code Organization
115+
- **New PHP code:** Use `src/` with dependency injection
116+
- **Legacy PHP:** Lives in `includes/`, prefer refactoring to `src/`
117+
- **Frontend:** React components in `client/` with TypeScript
118+
- **Tests:** Mirror source structure in `tests/unit/` for PHP
119+
120+
### Testing Conventions
121+
- PHP tests use PHPUnit and follow WordPress testing practices
122+
- JS tests use Jest with @wordpress/scripts preset
123+
- Co-locate JS tests with source files or in `__tests__/` directories
124+
- PHP tests run in Docker via `npm run test:php` (see `bin/run-tests.sh`)
125+
126+
### Git Workflow
127+
- Main branch for PRs: `develop`
128+
- Release branch: `trunk`
129+
- Husky manages git hooks
130+
- **Before creating a PR:**
131+
- Must run `npm run changelog add` and commit the changelog entry (choose 'patch' if change is not significant)
132+
- Changelog must be committed and pushed before creating the PR
133+
- Use PR template from `.github/PULL_REQUEST_TEMPLATE.md` when creating pull requests
134+
- Include testing instructions
135+
- Check mobile testing requirement
136+
- Link to release testing docs post-merge
137+
138+
### Docker Environment
139+
- WordPress: http://localhost:8082
140+
- phpMyAdmin: http://localhost:8083
141+
- MySQL: localhost:5678
142+
- Xdebug ready (requires IDE path mapping)
143+
144+
### Dependency Management
145+
- WordPress dependencies extracted automatically via webpack plugin
146+
- External packages added via `requestToExternal` and `requestToHandle` in webpack.config.js
147+
- Use Composer for PHP dependencies
148+
- Use npm for JavaScript dependencies
149+
150+
### Changelog
151+
- Use `npm run changelog` to add entries
152+
- Types: Add, Fix, Update, Dev
153+
- Entries go in `changelog/` directory
154+
155+
## Important Configuration Files
156+
157+
| File | Purpose |
158+
|------|---------|
159+
| `package.json` | npm scripts and dependencies |
160+
| `composer.json` | PHP dependencies and autoloading |
161+
| `webpack.config.js` | Main webpack entry |
162+
| `phpunit.xml.dist` | PHPUnit configuration |
163+
| `phpcs.xml.dist` | PHP coding standards |
164+
| `tests/js/jest.config.js` | Jest configuration |
165+
| `tests/e2e/playwright.config.ts` | E2E test config |
166+
| `tsconfig.json` | TypeScript configuration |
167+
| `.eslintrc` | ESLint rules |
168+
169+
## Version Support Policy
170+
- WordPress: Strict L-2 (supports current and 2 previous major versions)
171+
- WooCommerce: Loose L-2
172+
- See `docs/version-support-policy.md` for details
173+
174+
## Documentation
175+
- `README.md` - Main setup and overview
176+
- `CONTRIBUTING.md` - Contribution guidelines
177+
- `tests/README.md` - Testing guide
178+
- `docker/README.md` - Docker setup
179+
- `includes/core/README.md` - Extensibility docs
180+
- `docs/` - Additional documentation
181+
182+
## Tips for Claude
183+
- Prefer editing existing files over creating new ones
184+
- Check both `src/` and `includes/` when searching for PHP code
185+
- React components follow WordPress coding patterns (@wordpress packages)
186+
- Test files mirror source structure
187+
- PHP tests require Docker - ensure it's running before executing tests
188+
- Use `npm run test:php` to run all tests or edit the command to pass PHPUnit filters

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ project.properties
1111
*.sublime-workspace
1212
.sublimelinterrc
1313
.cursor/
14-
.claude/
14+
**/.claude/**/*.local.*
1515
.zed/
1616
.phpactor.json
1717

changelog.txt

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

3+
= 10.2.0 - 2025-11-06 =
4+
* Add - Add WooCommerce Tool to delete test orders.
5+
* Add - Sync store setup details with the Transact Platform.
6+
* Fix - Comment: fix JCB logo.
7+
* Fix - Fix - WCPay Subscriptions setting not persisting when unchecked
8+
* Fix - Fix missing payment method logos (JCB, CUP, CB) in checkout.
9+
* Fix - Fix payment method logos overflow in shortcode checkout after adding JCB and UnionPay logos.
10+
* Fix - Only show WooPay error messages for connection errors in available countries.
11+
* Fix - Prevent Express Checkout from being disabled on product page when updating quantity of variable products.
12+
* Fix - Prevent WooPayments-specific styles for the Checkout block to leak to other payment methods
13+
* Fix - Use Woo custom cap `pay_for_order` for validating the owner of order
14+
* Update - Avoid loading shipping zones when adjusting currencies for free shipping methods.
15+
* Update - Hide bundled subscription management UI while preserving renewal processing functionality
16+
* Update - Minor copy update to the delete test orders tool.
17+
* Update - Show message about bundled subscriptions until 10.2.0.
18+
* Dev - Add CLAUDE.md file to improve AI code assistance.
19+
* Dev - Bump WC tested up to version to 10.3.0.
20+
321
= 10.1.1 - 2025-10-27 =
422
* Fix - Overrides the core `AbstractAutomatticAddressProvider`'s `load_scripts` method to only run if the core setting (`woocommerce_address_autocomplete_enabled` is enabled).
523

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/blocks/payment-methods-logos/style.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,9 @@
5353
box-shadow: 0 0 0 1px rgba( 0, 0, 0, 0.1 );
5454
}
5555
}
56+
57+
.payment-methods--logos-popover {
58+
> img {
59+
object-position: center !important;
60+
}
61+
}

client/checkout/blocks/style.scss

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ button.wcpay-stripelink-modal-trigger:hover {
4444

4545
.wc-block-checkout__payment-method {
4646
input:checked ~ div {
47-
.wc-block-components-radio-control__label {
47+
/* stylelint-disable-next-line selector-id-pattern */
48+
.wc-block-components-radio-control__label:where( [id^='radio-control-wc-payment-method-options-woocommerce_payments'][id$='__label'] ) {
4849
> .payment-method-label {
4950
.test-mode.badge {
5051
// hiding the badge when the payment method is not selected
@@ -54,7 +55,8 @@ button.wcpay-stripelink-modal-trigger:hover {
5455
}
5556
}
5657

57-
.wc-block-components-radio-control__label {
58+
/* stylelint-disable-next-line selector-id-pattern */
59+
.wc-block-components-radio-control__label:where( [id^='radio-control-wc-payment-method-options-woocommerce_payments'][id$='__label'] ) {
5860
width: 100%;
5961
display: block !important;
6062

client/checkout/classic/event-handlers.js

Lines changed: 8 additions & 20 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,27 +178,18 @@ 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() {
192-
const paymentMethodElement = document.querySelector(
193-
'.payment_method_woocommerce_payments'
194-
);
195-
if ( ! paymentMethodElement ) {
196-
return 4; // Default fallback
197-
}
184+
// Use viewport width as primary indicator (similar to blocks checkout)
185+
const viewportWidth = window.innerWidth;
198186

199-
const elementWidth = paymentMethodElement.offsetWidth;
200-
if ( elementWidth <= 300 ) {
187+
// Specific tablet viewport range (768-781px) - needs room for Test Mode badge
188+
if ( viewportWidth >= 768 && viewportWidth <= 900 ) {
201189
return 1;
202-
} else if ( elementWidth <= 330 ) {
203-
return 2;
204190
}
191+
// Default - show 3 logos + counter badge = 4 visual elements total
192+
return 3;
205193
}
206194

207195
function shouldHavePopover() {

client/checkout/classic/style.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@
4141
img:last-of-type {
4242
margin-right: 0;
4343
}
44+
45+
&-count {
46+
margin-left: 4px;
47+
48+
// Tighter spacing on tablet viewports (768-900px) to conserve space for Test Mode badge
49+
@media ( min-width: 768px ) and ( max-width: 900px ) {
50+
margin-left: 0;
51+
}
52+
}
4453
}
4554
img {
4655
float: right;

0 commit comments

Comments
 (0)