PluginProbe
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions / 260927
s2Member – Excellent for All Kinds of Memberships, Content Restriction Paywalls & Member Access Subscriptions v260927
260927 260917 260913 260909 260829 260814 260805 110710 110731 110812 110815 110912 110913 110915 110926 110927 111002 111003 111011 111017 111029 111105 111206 111216 111220 All 190 releases
← All changes | src/includes/classes/paypal-utilities.inc.php +19 -13 260909 → 260927 View file →
@@ -120,9 +120,10 @@
120 120
121 121 $postvars = self::paypal_postvars_utf8($postvars);
122 122 $endpoint = ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["paypal_sandbox"]) ? "www.sandbox.paypal.com" : "www.paypal.com";
123 123
124 - if(!empty($_REQUEST["s2member_paypal_proxy"]) && !empty($_REQUEST["s2member_paypal_proxy_verification"]) && $_REQUEST["s2member_paypal_proxy_verification"] === c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen())
124 + //260909.0411 Normalize proxy verification input types and use the standard constant-time comparison helper.
125 + if(!empty($_REQUEST["s2member_paypal_proxy"]) && is_string($_REQUEST["s2member_paypal_proxy"]) && !empty($_REQUEST["s2member_paypal_proxy_verification"]) && is_string($_REQUEST["s2member_paypal_proxy_verification"]) && is_string($proxy_verification_key = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()) && hash_equals($proxy_verification_key, $_REQUEST["s2member_paypal_proxy_verification"]))
125 126 return apply_filters("ws_plugin__s2member_paypal_postvars", array_merge($postvars, array("proxy_verified" => $_REQUEST["s2member_paypal_proxy"])), get_defined_vars());
126 127
127 128 else if(empty($_POST) && !empty($_GET["s2member_paypal_proxy"]) && !empty($_GET["s2member_paypal_proxy_verification"]) && c_ws_plugin__s2member_utils_urls::s2member_sig_ok($_SERVER["REQUEST_URI"], false, false, "s2member_paypal_proxy_verification"))
128 129 return apply_filters("ws_plugin__s2member_paypal_postvars", array_merge($postvars, array("proxy_verified" => $_GET["s2member_paypal_proxy"])), get_defined_vars());
@@ -323,10 +324,15 @@
323 324 if(is_multisite() && !is_main_site())
324 325 $key = md5(c_ws_plugin__s2member_utils_encryption::xencrypt(strtolower($current_blog->domain.$current_blog->path), false, false));
325 326
326 327 else {
327 - $host = ($GLOBALS['WS_PLUGIN__']['s2member']['o']['skip_ipn_domain_validation']) ? parse_url(home_url('/'), PHP_URL_HOST) : $_SERVER["HTTP_HOST"]; //250917
328 - $key = md5(c_ws_plugin__s2member_utils_encryption::xencrypt(preg_replace("/\:[0-9]+$/", "", strtolower((string) $host)), false, false));
328 + //260909.0217 Normalize host selection so proxy verification behaves consistently across different server configurations.
329 + $site_host = preg_replace("/\:[0-9]+$/", "", strtolower((string)parse_url(home_url('/'), PHP_URL_HOST)));
330 + $request_host = (!empty($_SERVER["HTTP_HOST"]) && is_string($_SERVER["HTTP_HOST"])) ? preg_replace("/\:[0-9]+$/", "", strtolower($_SERVER["HTTP_HOST"])) : '';
331 + $host = ($GLOBALS['WS_PLUGIN__']['s2member']['o']['skip_ipn_domain_validation']) ? $site_host : $request_host;
332 + $host = strlen($host) ? $host : $site_host;
333 + $host = strlen($host) ? $host : 's2member-paypal-proxy'; //260909.0338 Provide a stable final fallback when no usable site host is available.
334 + $key = md5(c_ws_plugin__s2member_utils_encryption::xencrypt($host, false, false));
329 335 }
330 336
331 337 return apply_filters("ws_plugin__s2member_paypal_proxy_key_gen", $key, get_defined_vars());
332 338 }
@@ -1554,9 +1560,9 @@
1554 1560 $gateway_checkout_lock = '';
1555 1561
1556 1562 if($gateway_checkout_id)
1557 1563 {
1558 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
1564 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
1559 1565 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'payment')
1560 1566 return array('__error' => 'gateway_checkout_invalid');
1561 1567
1562 1568 //260902.0635 Return an already-persisted PayPal order before another provider create; a lost browser response can therefore resume the same logical purchase.
@@ -1567,9 +1573,9 @@
1567 1573 $gateway_checkout_lock = c_ws_plugin__s2member_gateway_checkouts::processing_lock($gateway_checkout_id);
1568 1574 if(!$gateway_checkout_lock)
1569 1575 return array('__error' => 'gateway_checkout_busy');
1570 1576
1571 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
1577 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
1572 1578 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'payment')
1573 1579 {
1574 1580 c_ws_plugin__s2member_gateway_checkouts::processing_unlock($gateway_checkout_id, $gateway_checkout_lock);
1575 1581 return array('__error' => 'gateway_checkout_invalid');
@@ -1850,9 +1856,9 @@
1850 1856
1851 1857 if($gateway_checkout_id)
1852 1858 {
1853 1859 //260907.1820 For coordinator-backed captures, the order ID already persisted server-side is authoritative; never let a browser-supplied order ID rebind this logical checkout to another PayPal resource.
1854 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
1860 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
1855 1861 $expected_order_id = $gateway_checkout && !empty($gateway_checkout['gateway_ids']['order_id']) ? (string)$gateway_checkout['gateway_ids']['order_id'] : '';
1856 1862 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'payment' || !$expected_order_id || !hash_equals($expected_order_id, $order_id))
1857 1863 return array('__error' => 'gateway_checkout_order_mismatch');
1858 1864
@@ -1878,9 +1884,9 @@
1878 1884 try
1879 1885 {
1880 1886 if($gateway_checkout_id)
1881 1887 {
1882 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
1888 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
1883 1889 if(!$gateway_checkout || empty($gateway_checkout['gateway_ids']['order_id']) || !hash_equals((string)$gateway_checkout['gateway_ids']['order_id'], $order_id))
1884 1890 return array('__error' => 'gateway_checkout_order_mismatch');
1885 1891
1886 1892 $gateway_status = !empty($gateway_checkout['gateway_status']) ? strtoupper((string)$gateway_checkout['gateway_status']) : '';
@@ -2030,9 +2036,9 @@
2030 2036 }
2031 2037
2032 2038 try
2033 2039 {
2034 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2040 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2035 2041 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'payment')
2036 2042 return array('handled' => FALSE, 'ok' => FALSE, 'error' => 'not_coordinator_checkout');
2037 2043
2038 2044 //260907.1820 Provider identities are immutable once learned: browser/webhook reconciliation may advance status only for the same PayPal order/capture and must never rebind a checkout to conflicting IDs.
@@ -2090,9 +2096,9 @@
2090 2096
2091 2097 if(!$gateway_checkout_id || ($completion_error = self::paypal_checkout_order_completion_error($order, $order_id, $token)))
2092 2098 return array('ok' => FALSE, 'error' => $completion_error ? $completion_error : 'gateway_checkout_invalid');
2093 2099
2094 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2100 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2095 2101 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'payment')
2096 2102 return array('ok' => FALSE, 'error' => 'gateway_checkout_invalid');
2097 2103
2098 2104 $private_context = c_ws_plugin__s2member_gateway_checkouts::private_context_get($gateway_checkout_id);
@@ -2282,9 +2288,9 @@
2282 2288
2283 2289 if(!$subscription_id || !c_ws_plugin__s2member_gateway_checkouts::valid_id($gateway_checkout_id))
2284 2290 return array('handled' => false, 'ok' => false, 'recovered' => false, 'error' => 'not_coordinator_checkout');
2285 2291
2286 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2292 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2287 2293 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'subscription')
2288 2294 return array('handled' => false, 'ok' => false, 'recovered' => false, 'error' => 'not_coordinator_checkout');
2289 2295
2290 2296 $lock = c_ws_plugin__s2member_gateway_checkouts::processing_lock($gateway_checkout_id, 60);
@@ -2292,9 +2298,9 @@
2292 2298 return array('handled' => true, 'ok' => false, 'recovered' => false, 'error' => 'gateway_checkout_busy', 'gateway_checkout_id' => $gateway_checkout_id);
2293 2299
2294 2300 try
2295 2301 {
2296 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2302 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2297 2303 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'subscription')
2298 2304 return array('handled' => true, 'ok' => false, 'recovered' => false, 'error' => 'gateway_checkout_invalid', 'gateway_checkout_id' => $gateway_checkout_id);
2299 2305
2300 2306 $existing_subscription_id = !empty($gateway_checkout['gateway_ids']['subscription_id']) ? (string)$gateway_checkout['gateway_ids']['subscription_id'] : '';
@@ -2350,9 +2356,9 @@
2350 2356 $gateway_checkout_lock = '';
2351 2357
2352 2358 if($gateway_checkout_id)
2353 2359 {
2354 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2360 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2355 2361 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'subscription')
2356 2362 return array('__error' => 'gateway_checkout_invalid');
2357 2363
2358 2364 //260901.2145 Return a previously persisted PayPal subscription before making another create request; this also recovers a browser reload after server-side creation succeeded.
@@ -2362,9 +2368,9 @@
2362 2368 $gateway_checkout_lock = c_ws_plugin__s2member_gateway_checkouts::processing_lock($gateway_checkout_id);
2363 2369 if(!$gateway_checkout_lock)
2364 2370 return array('__error' => 'gateway_checkout_busy');
2365 2371
2366 - $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::get($gateway_checkout_id);
2372 + $gateway_checkout = c_ws_plugin__s2member_gateway_checkouts::load_state($gateway_checkout_id);
2367 2373 if(!$gateway_checkout || (string)$gateway_checkout['gateway'] !== 'paypal_checkout' || (string)$gateway_checkout['operation'] !== 'subscription')
2368 2374 {
2369 2375 c_ws_plugin__s2member_gateway_checkouts::processing_unlock($gateway_checkout_id, $gateway_checkout_lock);
2370 2376 return array('__error' => 'gateway_checkout_invalid');