-
Notifications
You must be signed in to change notification settings - Fork 69
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
Respect BNPL limits_per_currency (country, min, max) #9626
Changes from all commits
abd89aa
632016e
2adf9ce
b9b8f75
7a7892a
5074bca
7d64f6a
613bb62
c4eae6c
3eae337
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: fix | ||
|
||
Prevent dead space on product pages when no BNPL offers are available. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -716,59 +716,163 @@ public static function get_filtered_error_status_code( Exception $e ): int { | |
} | ||
|
||
/** | ||
* Retrieves Stripe minimum order value authorized per currency. | ||
* The values are based on Stripe's recommendations. | ||
* See https://docs.stripe.com/currencies#minimum-and-maximum-charge-amounts. | ||
* Get the BNPL limits per currency for a specific payment method. | ||
* | ||
* @param string $currency The currency. | ||
* | ||
* @return int The minimum amount. | ||
* @param string $payment_method The payment method name ('affirm', 'afterpay_clearpay', or 'klarna'). | ||
* @return array The BNPL limits per currency for the specified payment method. | ||
*/ | ||
public static function get_stripe_minimum_amount( $currency ) { | ||
switch ( $currency ) { | ||
case 'AED': | ||
case 'MYR': | ||
case 'PLN': | ||
case 'RON': | ||
$minimum_amount = 200; | ||
break; | ||
case 'BGN': | ||
$minimum_amount = 100; | ||
break; | ||
case 'CZK': | ||
$minimum_amount = 1500; | ||
break; | ||
case 'DKK': | ||
$minimum_amount = 250; | ||
break; | ||
case 'GBP': | ||
$minimum_amount = 30; | ||
break; | ||
case 'HKD': | ||
$minimum_amount = 400; | ||
break; | ||
case 'HUF': | ||
$minimum_amount = 17500; | ||
break; | ||
case 'JPY': | ||
$minimum_amount = 5000; | ||
break; | ||
case 'MXN': | ||
case 'THB': | ||
$minimum_amount = 1000; | ||
break; | ||
case 'NOK': | ||
case 'SEK': | ||
$minimum_amount = 300; | ||
break; | ||
Comment on lines
-727
to
-763
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mentioned in the PR description, this was added to handle BNPL minimum amounts but is actually comprised of Stripe minimum amounts. It's was only used for that purpose and is safe to remove. |
||
public static function get_bnpl_limits_per_currency( $payment_method ) { | ||
switch ( $payment_method ) { | ||
case 'affirm': | ||
return [ | ||
Currency_Code::CANADIAN_DOLLAR => [ | ||
Country_Code::CANADA => [ | ||
'min' => 5000, | ||
'max' => 3000000, | ||
], // Represents CAD 50 - 30,000 CAD. | ||
], | ||
Currency_Code::UNITED_STATES_DOLLAR => [ | ||
Country_Code::UNITED_STATES => [ | ||
'min' => 5000, | ||
'max' => 3000000, | ||
], | ||
], // Represents USD 50 - 30,000 USD. | ||
]; | ||
case 'afterpay_clearpay': | ||
return [ | ||
Currency_Code::AUSTRALIAN_DOLLAR => [ | ||
Country_Code::AUSTRALIA => [ | ||
'min' => 100, | ||
'max' => 200000, | ||
], // Represents AUD 1 - 2,000 AUD. | ||
], | ||
Currency_Code::CANADIAN_DOLLAR => [ | ||
Country_Code::CANADA => [ | ||
'min' => 100, | ||
'max' => 200000, | ||
], // Represents CAD 1 - 2,000 CAD. | ||
], | ||
Currency_Code::NEW_ZEALAND_DOLLAR => [ | ||
Country_Code::NEW_ZEALAND => [ | ||
'min' => 100, | ||
'max' => 200000, | ||
], // Represents NZD 1 - 2,000 NZD. | ||
], | ||
Currency_Code::POUND_STERLING => [ | ||
Country_Code::UNITED_KINGDOM => [ | ||
'min' => 100, | ||
'max' => 120000, | ||
], // Represents GBP 1 - 1,200 GBP. | ||
], | ||
Currency_Code::UNITED_STATES_DOLLAR => [ | ||
Country_Code::UNITED_STATES => [ | ||
'min' => 100, | ||
'max' => 400000, | ||
], // Represents USD 1 - 4,000 USD. | ||
], | ||
]; | ||
case 'klarna': | ||
return [ | ||
Currency_Code::UNITED_STATES_DOLLAR => [ | ||
Country_Code::UNITED_STATES => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents USD 1 - 10,000 USD. | ||
], | ||
Currency_Code::POUND_STERLING => [ | ||
Country_Code::UNITED_KINGDOM => [ | ||
'min' => 100, | ||
'max' => 500000, | ||
], // Represents GBP 1 - 5,000 GBP. | ||
], | ||
Currency_Code::EURO => [ | ||
Country_Code::AUSTRIA => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents EUR 1 - 10,000 EUR. | ||
Country_Code::BELGIUM => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents EUR 1 - 10,000 EUR. | ||
Country_Code::GERMANY => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents EUR 1 - 10,000 EUR. | ||
Country_Code::NETHERLANDS => [ | ||
'min' => 100, | ||
'max' => 500000, | ||
], // Represents EUR 1 - 5,000 EUR. | ||
Country_Code::FINLAND => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents EUR 1 - 10,000 EUR. | ||
Country_Code::SPAIN => [ | ||
'min' => 100, | ||
'max' => 1000000, | ||
], // Represents EUR 1 - 10,000 EUR. | ||
Country_Code::IRELAND => [ | ||
'min' => 100, | ||
'max' => 400000, | ||
], // Represents EUR 1 - 4,000 EUR. | ||
Country_Code::ITALY => [ | ||
'min' => 100, | ||
'max' => 400000, | ||
], // Represents EUR 1 - 4,000 EUR. | ||
Country_Code::FRANCE => [ | ||
'min' => 100, | ||
'max' => 400000, | ||
], // Represents EUR 1 - 4,000 EUR. | ||
], | ||
Currency_Code::DANISH_KRONE => [ | ||
Country_Code::DENMARK => [ | ||
'min' => 100, | ||
'max' => 10000000, | ||
], // Represents DKK 1 - 100,000 DKK. | ||
], | ||
Currency_Code::NORWEGIAN_KRONE => [ | ||
Country_Code::NORWAY => [ | ||
'min' => 100, | ||
'max' => 10000000, | ||
], // Represents NOK 1 - 100,000 NOK. | ||
], | ||
Currency_Code::SWEDISH_KRONA => [ | ||
Country_Code::SWEDEN => [ | ||
'min' => 100, | ||
'max' => 10000000, | ||
], // Represents SEK 1 - 100,000 SEK. | ||
], | ||
]; | ||
default: | ||
$minimum_amount = 50; | ||
break; | ||
return []; | ||
} | ||
} | ||
|
||
self::cache_minimum_amount( $currency, $minimum_amount ); | ||
/** | ||
* Check if any BNPL method is available for a given country, currency, and price. | ||
* | ||
* @param array $enabled_methods Array of enabled BNPL methods. | ||
* @param string $country_code Country code. | ||
* @param string $currency_code Currency code. | ||
* @param float $price Product price. | ||
* @return bool True if any BNPL method is available, false otherwise. | ||
*/ | ||
public static function is_any_bnpl_method_available( array $enabled_methods, string $country_code, string $currency_code, float $price ): bool { | ||
$price_in_cents = $price; | ||
|
||
foreach ( $enabled_methods as $method ) { | ||
$limits = self::get_bnpl_limits_per_currency( $method ); | ||
|
||
return $minimum_amount; | ||
if ( isset( $limits[ $currency_code ][ $country_code ] ) ) { | ||
$min_amount = $limits[ $currency_code ][ $country_code ]['min']; | ||
$max_amount = $limits[ $currency_code ][ $country_code ]['max']; | ||
|
||
if ( $price_in_cents >= $min_amount && $price_in_cents <= $max_amount ) { | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
|
@@ -785,20 +889,12 @@ public static function cache_minimum_amount( $currency, $amount ) { | |
* Checks if there is a minimum amount required for transactions in a given currency. | ||
* | ||
* @param string $currency The currency to check for. | ||
* @param bool $fallback_to_local_list Whether to fallback to the local Stripe list if the cached value is not available. | ||
* | ||
* @return int|null Either the minimum amount, or `null` if not available. | ||
*/ | ||
public static function get_cached_minimum_amount( $currency, $fallback_to_local_list = false ) { | ||
public static function get_cached_minimum_amount( $currency ) { | ||
$cached = get_transient( 'wcpay_minimum_amount_' . strtolower( $currency ) ); | ||
|
||
if ( (int) $cached ) { | ||
return (int) $cached; | ||
} elseif ( $fallback_to_local_list ) { | ||
return self::get_stripe_minimum_amount( $currency ); | ||
} | ||
|
||
return null; | ||
return (int) $cached ? (int) $cached : null; | ||
} | ||
Comment on lines
+895
to
898
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the previous comment, reverting this back to it's state prior to #9355. |
||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just ensures we're getting all of the enabled BNPL payment methods.
get_payment_method_ids_enabled_at_checkout()
is a filtered list for checkout. This means, if you visit a PDP while you have products in the cart, you might not see the correct BNPL methods in the PMME. For example, with a $5 product in the cart, a $60 PDP won't display Affirm ($50 minimum) because it's been filtered out based on cart totals. Demo here, second example from the bottom. This change solves that.