Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: For Shipping Zones Zip Regex - Correctly handle UK postcodes redacted by Apple Pay #3592

Merged
merged 12 commits into from
Dec 26, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,27 @@ public function get_normalized_postal_code( $postcode, $country ) {
if ( 'GB' === $country ) {
// Replaces a redacted string with something like LN10***.
return str_pad( preg_replace( '/\s+/', '', $postcode ), 7, '*' );
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
// UK Postcodes returned from Apple Pay can be alpha numeric 2 chars, 3 chars, or 4 chars long will optionally have a trailing space,
// depending on whether the customer put a space in their postcode between the outcode and incode part.
// See https://assets.publishing.service.gov.uk/media/5a7b997d40f0b62826a049e0/ILRSpecification2013_14Appendix_C_Dec2012_v1.pdf for more details.

// Here is a table showing the functionality by example:
// Original | Apple Pay | Normalized
// 'LN10 1AA' | 'LN10 ' | 'LN10 ***'
// 'LN101AA' | 'LN10' | 'LN10 ***'
// 'W10 2AA' | 'W10 ' | 'W10 ***'
// 'W102AA' | 'W10' | 'W10 ***'
// 'N2 3AA | 'N2 ' | 'N2 ***'
// 'N23AA | 'N2' | 'N2 ***'

$spaceless_postcode = preg_replace( '/\s+/', '', $postcode );

if ( strlen($spaceless_postcode) < 5) {
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
// Always reintroduce the space so that Shipping Zones regex like 'N1 *' work to match N1 postcodes like N1 1AA, but don't match N10 postcodes like N10 1AA
return $spaceless_postcode . " ***";
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
} else {
return $postcode; // 5 or more chars means it probably wasn't redacted and will likely validate unchanged.
}
}
if ( 'CA' === $country ) {
// Replaces a redacted string with something like L4Y***.
Expand Down
29 changes: 25 additions & 4 deletions includes/payment-methods/class-wc-stripe-payment-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,34 @@ public function filter_gateway_title( $title, $id ) {
*/
public function get_normalized_postal_code( $postcode, $country ) {
/**
* Currently, Apple Pay truncates the UK and Canadian postal codes to the first 4 and 3 characters respectively
* when passing it back from the shippingcontactselected object. This causes WC to invalidate
* Currently, Apple Pay truncates the UK postcodes by removing the "inward" (last 3 chars) of the postcode.
* Apple Pay also truncates Canadian postal codes to the first 4 characters.
* When either of these are passed back from the shippingcontactselected object. This causes WC to invalidate
* the postal code and not calculate shipping zones correctly.
*
*/
if ( 'GB' === $country ) {
// Replaces a redacted string with something like LN10***.
return str_pad( preg_replace( '/\s+/', '', $postcode ), 7, '*' );
// UK Postcodes returned from Apple Pay can be alpha numeric 2 chars, 3 chars, or 4 chars long will optionally have a trailing space,
// depending on whether the customer put a space in their postcode between the outcode and incode part.
// See https://assets.publishing.service.gov.uk/media/5a7b997d40f0b62826a049e0/ILRSpecification2013_14Appendix_C_Dec2012_v1.pdf for more details.

// Here is a table showing the functionality by example:
// Original | Apple Pay | Normalized
// 'LN10 1AA' | 'LN10 ' | 'LN10 ***'
// 'LN101AA' | 'LN10' | 'LN10 ***'
// 'W10 2AA' | 'W10 ' | 'W10 ***'
// 'W102AA' | 'W10' | 'W10 ***'
// 'N2 3AA | 'N2 ' | 'N2 ***'
// 'N23AA | 'N2' | 'N2 ***'

$spaceless_postcode = preg_replace( '/\s+/', '', $postcode );

if ( strlen($spaceless_postcode) < 5) {
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
// Always reintroduce the space so that Shipping Zones regex like 'N1 *' work to match N1 postcodes like N1 1AA, but don't match N10 postcodes like N10 1AA
return $spaceless_postcode . " ***";
wjrosa marked this conversation as resolved.
Show resolved Hide resolved
} else {
return $postcode; // 5 or more chars means it probably wasn't redacted and will likely validate unchanged.
}
}
if ( 'CA' === $country ) {
// Replaces a redacted string with something like L4Y***.
Expand Down
Loading