'', 'coupon_code' => '', 'affiliate_id' => ''); $coupon = c_ws_plugin__s2member_utils_strings::strip_php_tags_deep($coupon); //260910.2249 Normalize proxy coupon data consistently with other notification values. if(!empty($paypal['txn_type']) && $paypal['txn_type'] === 'merch_pmt') // This is mostly irrelevant, but it helps to keep the logs cleaner. sleep(15); // Wait for Pro-Form procesing to complete. if(empty($paypal['custom']) && !empty($paypal['recurring_payment_id'])) // Recurring Profile ID. $paypal['custom'] = c_ws_plugin__s2member_utils_users::get_user_custom_with($paypal['recurring_payment_id']); else if(empty($paypal['custom']) && !empty($paypal['mp_id'])) // Billing Agreement ID. $paypal['custom'] = c_ws_plugin__s2member_utils_users::get_user_custom_with($paypal['mp_id']); //250522 At least set it to an empty string. else if(empty($paypal['custom'])) $paypal['custom'] = ''; //260910.0356 Resolve the expected host consistently across different web-server request environments. $ipn_host = (!empty($_SERVER['HTTP_HOST']) && is_string($_SERVER['HTTP_HOST'])) ? preg_replace('/\:([0-9]+)$/', '', $_SERVER['HTTP_HOST']) : (string)parse_url(home_url('/'), PHP_URL_HOST); //250606 Added option to skip domain validation. if ($GLOBALS['WS_PLUGIN__']['s2member']['o']['skip_ipn_domain_validation'] || ($ipn_host !== '' && !empty($paypal['custom']) && preg_match('/^'.preg_quote($ipn_host, '/').'/i', $paypal['custom']))) { if ($GLOBALS['WS_PLUGIN__']['s2member']['o']['skip_ipn_domain_validation']) $paypal['s2member_log'][] = 's2Member originating domain validation was skipped.'; else $paypal['s2member_log'][] = 's2Member originating domain (`$_SERVER["HTTP_HOST"]`) validated.'; foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; if(!apply_filters('ws_plugin__s2member_during_paypal_notify_conditionals', FALSE, get_defined_vars())) { unset($__refs, $__v); // From the filter above. if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_virtual_terminal::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_express_checkout::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_cart::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_send_money::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_web_accept_sp::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_wa_ccaps_wo_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_wa_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_rec_profile_creation_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_modify_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_payment_failed_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_cancellation_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_subscr_or_rp_eots_w_level::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_sp_refund_reversal::cp(get_defined_vars()))) $paypal = $_paypal_cp; else if(($_paypal_cp = c_ws_plugin__s2member_paypal_notify_in_billing_agreement_signup::cp(get_defined_vars()))) $paypal = $_paypal_cp; else // Ignoring this IPN request. The txn_type/status does NOT require any action. $paypal['s2member_log'][] = 'Ignoring this IPN request. The `txn_type/status` does NOT require any action on the part of s2Member.'; } else unset($__refs, $__v); // Else a custom conditional has been applied by Filters. } else if(!empty($paypal['txn_type']) && preg_match('/^recurring_payment_profile_cancel$/i', $paypal['txn_type'])) { $paypal['s2member_log'][] = 'Transaction type (`recurring_payment_profile_cancel`), but there is no match to an existing account; so verification of `$_SERVER["HTTP_HOST"]` was not possible.'; $paypal['s2member_log'][] = 'It\'s likely this account was just upgraded/downgraded by s2Member Pro; so the Subscr. ID has probably been updated on-site; nothing to worry about here.'; } else if(!empty($paypal['txn_type']) && preg_match('/^recurring_/i', $paypal['txn_type'])) // Otherwise, is this a ^recurring_ txn_type? $paypal['s2member_log'][] = 'Transaction type (`^recurring_?`), but there is no match to an existing account; so verification of `$_SERVER["HTTP_HOST"]` was not possible.'; else // Else, use the default ``$_SERVER['HTTP_HOST']`` error. $paypal['s2member_log'][] = 'Unable to verify `$_SERVER["HTTP_HOST"]`. Please check the `custom` value in your Button Code. It MUST start with your domain name.'; } else // Extensive log reporting here. This is an area where many site owners find trouble. Depending on server configuration; remote HTTPS connections may fail. { if (!empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET' && !empty($_SERVER['HTTP_USER_AGENT'])) { if (preg_match('/(msie|trident|gecko|webkit|presto|konqueror|playstation)[\/ ]([0-9\.]+)/i', $_SERVER['HTTP_USER_AGENT'])) { $paypal['s2member_indicator'] = 'This PayPal IPN Handler by s2Member® is active & listening.'; } } $paypal['s2member_log'][] = 'Unable to verify $_POST vars. This is most likely related to an invalid configuration of s2Member, or a problem with server compatibility.'; $paypal['s2member_log'][] = 'Please see this KB article: `http://www.s2member.com/kb/server-scanner/`. We suggest that you run the s2Member Server Scanner.'; $paypal['s2member_log'][] = var_export($_REQUEST, TRUE); // Recording _POST + _GET vars for analysis and debugging. } if($email_configs_were_on) // Back on? c_ws_plugin__s2member_email_configs::email_config(); /* Add IPN proxy (when available) to the ``$paypal`` array. */ if(!empty($_REQUEST['s2member_paypal_proxy'])) $paypal['s2member_paypal_proxy'] = esc_html(trim(stripslashes((string)$_REQUEST['s2member_paypal_proxy']))); /* Add IPN proxy use vars (when available) to the ``$paypal`` array. */ if(!empty($_REQUEST['s2member_paypal_proxy_use'])) $paypal['s2member_paypal_proxy_use'] = esc_html(trim(stripslashes((string)$_REQUEST['s2member_paypal_proxy_use']))); /* Add IPN proxy coupon vars (when available) to the ``$paypal`` array. */ if(!empty($_REQUEST['s2member_paypal_proxy_coupon'])) $paypal['s2member_paypal_proxy_coupon'] = stripslashes_deep((array)$_REQUEST['s2member_paypal_proxy_coupon']); /* Also add IPN proxy self-verification (when available) to the ``$paypal`` array. */ if(!empty($_REQUEST['s2member_paypal_proxy_verification'])) $paypal['s2member_paypal_proxy_verification'] = esc_html(trim(stripslashes((string)$_REQUEST['s2member_paypal_proxy_verification']))); /* Log this IPN post-processing event now. */ c_ws_plugin__s2member_utils_logs::log_entry('gateway-core-ipn', $paypal); /* Hook during core IPN post-processing might be useful for developers. */ foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_during_paypal_notify', get_defined_vars()); unset($__refs, $__v); /* 260322 Log effective response state before/after forcing a 200. Output response headers & content body. */ $paypal['s2member_log'][] = 'Pre-response `headers_sent`: '.((headers_sent($headers_sent_file, $headers_sent_line)) ? 'yes @ '.$headers_sent_file.':'.$headers_sent_line : 'no'); $paypal['s2member_log'][] = 'Pre-response `http_response_code()`: '.((function_exists('http_response_code')) ? (string)http_response_code() : 'n/a'); $paypal['s2member_log'][] = 'Pre-response headers: '.var_export(headers_list(), TRUE); while(@ob_end_clean()); // Clean output buffers. if(function_exists('http_response_code')) http_response_code(200); if(!empty($_SERVER['SERVER_PROTOCOL'])) header($_SERVER['SERVER_PROTOCOL'].' 200 OK', TRUE, 200); else header('HTTP/1.1 200 OK', TRUE, 200); status_header(200); // OK status code. header('Content-Type: text/plain; charset=UTF-8'); $paypal['s2member_log'][] = 'Post-response `http_response_code()`: '.((function_exists('http_response_code')) ? (string)http_response_code() : 'n/a'); $paypal['s2member_log'][] = 'Post-response headers: '.var_export(headers_list(), TRUE); if (!empty($paypal['s2member_paypal_proxy_return_url'])) { if(preg_match('/^https?%3A/ui', $paypal['s2member_paypal_proxy_return_url'])) { $paypal['s2member_paypal_proxy_return_url'] = urldecode($paypal['s2member_paypal_proxy_return_url']); } // See: exit($paypal['s2member_paypal_proxy_return_url']); } elseif (!empty($paypal['s2member_indicator'])) { exit($paypal['s2member_indicator']); } else { exit(); // Default behavior. } } foreach(array_keys(get_defined_vars()) as $__v) $__refs[$__v] =& $$__v; do_action('ws_plugin__s2member_after_paypal_notify', get_defined_vars()); unset($__refs, $__v); } } }