/** * Calls upon Authorize.Net® AIM, and returns the response. * * @package s2Member\AuthNet * @since 1.5 * * @param array $post_vars An array of variables to send through the Authorize.Net® API call. * @return array An array of variables returned from the API call. * * @todo Continue optimizing this routine with ``empty()`` and ``isset()``. */ public static function authnet_aim_response($post_vars = FALSE) { global $current_site, $current_blog; /* For Multisite support. */ /**/ $url = "https://" . ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_authnet_sandbox"] ? "test.authorize.net" : "secure.authorize.net") . "/gateway/transact.dll"; /**/ $post_vars = is_array($post_vars) ? $post_vars : array(); /* Must be in array format. */ /**/ $post_vars["x_version"] = "3.1"; /* Configure the Authorize.Net® transaction version. */ $post_vars["x_login"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_authnet_api_login_id"]; $post_vars["x_tran_key"] = $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_authnet_api_trans_key"]; /**/ $post_vars["x_delim_data"] = "true"; /* Yes, return a delimited string. */ $post_vars["x_delim_char"] = ","; /* Fields delimitation character. */ $post_vars["x_encap_char"] = '"'; /* Field encapsulation character. */ /**/ $post_vars["x_invoice_num"] = !empty($post_vars["x_invoice_num"]) ? substr($post_vars["x_invoice_num"], 0, 20) : ""; $post_vars["x_description"] = !empty($post_vars["x_description"]) ? substr($post_vars["x_description"], 0, 255) : ""; $post_vars["x_description"] = c_ws_plugin__s2member_utils_strings::strip_2_kb_chars($post_vars["x_description"]); /**/ $input_time = date("D M j, Y g:i:s a T"); /* Record input time for logging. */ /**/ $csv = trim(c_ws_plugin__s2member_utils_urls::remote($url, $post_vars, array("timeout" => 20))); /**/ $output_time = date("D M j, Y g:i:s a T"); /* Now record after output time. */ /**/ $response = $csv ? c_ws_plugin__s2member_utils_strings::trim_dq_deep(preg_split("/\",\"/", $csv)) : array(); $response = c_ws_plugin__s2member_utils_strings::trim_deep(stripslashes_deep($response)); /**/ foreach (array("response_code", "response_subcode", "response_reason_code", "response_reason_text", "authorization_code", "avs_response", "transaction_id", "invoice_number", "description", "amount", "method", "transaction_type", "customer_id", "first_name", "last_name", "company", "address", "city", "state", "zipcode", "country", "phone", "fax", "email", "ship_to_first_name", "ship_to_last_name", "ship_to_company", "ship_to_address", "ship_to_city", "ship_to_state", "ship_to_zipcode", "ship_to_country", "tax", "duty", "freight", "tax_exempt", "po_number", "md5_hash", "card_code_response", "cavv_response", "card_number", "card_type", "split_tender_id", "requested_amount", "balance_on_card") as $order => $field_name) { $response[$field_name] = isset($response[$order]) ? $response[$order] : null; } /**/ if (empty($response["response_code"]) || $response["response_code"] !== "1") { if (strlen($response["response_reason_code"]) || $response["response_reason_text"]) { /* translators: Exclude `%2$s`. This is an English error returned by Authorize.Net®. Please replace `%2$s` with: `Unable to process, please try again`, or something to that affect. Or, if you prefer, you could Filter ``$response["__error"]`` with `ws_plugin__s2member_pro_authnet_aim_response`. */ $response["__error"] = sprintf(_x('Error #%1$s. %2$s.', "s2member-front", "s2member"), $response["response_reason_code"], rtrim($response["response_reason_text"], ".")); } else { /* Else, generate an error messsage - so something is reported back to the Customer. */ $response["__error"] = _x("Error. Please contact Support for assistance.", "s2member-front", "s2member"); } } /* If debugging is enabled; we need to maintain a comprehensive log file. Logging now supports Multisite Networking as well. */ $logv = c_ws_plugin__s2member_utilities::ver_details(); $logm = c_ws_plugin__s2member_utilities::mem_details(); $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"]; $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4; $log2 = is_multisite() && !is_main_site() ? "authnet-api-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "authnet-api.log"; /**/ if (strlen($post_vars["x_card_num"]) > 4) { /* Only log last 4 digits for security. */ $post_vars["x_card_num"] = str_repeat("*", strlen($post_vars["x_card_num"]) - 4) . substr($post_vars["x_card_num"], -4); } /* Then display last 4 digits. */ /**/ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) { if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) { if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) { if ($log = "-------- Input vars: ( " . $input_time . " ) --------\n" . var_export($post_vars, true) . "\n") { if ($log .= "-------- Output string/vars: ( " . $output_time . " ) --------\n" . $csv . "\n" . var_export($response, true)) { file_put_contents($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . $log . "\n\n", FILE_APPEND); } } } } } /**/ return apply_filters("ws_plugin__s2member_pro_authnet_aim_response", c_ws_plugin__s2member_pro_authnet_utilities::_authnet_aim_response_filters($response), get_defined_vars()); }
/** * Connect to and process DataLink information for ccBill. * * s2Member's Auto EOT System must be enabled for this to work properly. * * If you have a HUGE userbase, increase the max IPNs per process. * But NOTE, this runs ``$per_process`` *(per Blog)* on a Multisite Network. * To increase, use: ``add_filter ("ws_plugin__s2member_pro_ccbill_datalink_ipns_per_process");``. * * @package s2Member\ccBill * @since 1.5 * * @attaches-to ``add_action("ws_plugin__s2member_after_auto_eot_system");`` * * @param array $vars Expects an array of defined variables passed in by the Action Hook. * @return null */ public static function ccbill_datalink($vars = FALSE) { global $wpdb; global $current_site, $current_blog; if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_id"]) { $mst_time_10m_ago = time() - 6 * 3600 - 600; $datalink = "https://datalink.ccbill.com/data/main.cgi"; if (!($last = get_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"))) || $last < $mst_time_10m_ago - 86400) { $start = $last && $last >= $mst_time_10m_ago - (86400 + 43200) ? $last : $mst_time_10m_ago - 86400; $end = $last = $start + 86400 <= $mst_time_10m_ago ? $start + 86400 : $mst_time_10m_ago; $dl_types = "REBILL" . ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_dl_cancellations"] || apply_filters("ws_plugin__s2member_pro_ccbill_datalink_pulls_cancellations", false) ? ",CANCELLATION" : "") . ",EXPIRE,REFUND,CHARGEBACK"; $qvrs = array("startTime" => date("YmdHis", $start), "endTime" => date("YmdHis", $end), "transactionTypes" => $dl_types, "clientAccnum" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_id"], "clientSubacc" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_sid"], "username" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_dl_user"], "password" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_dl_pass"]); if (($unprocessed_ipn_lines = trim(c_ws_plugin__s2member_utils_urls::remote($datalink = add_query_arg(urlencode_deep($qvrs), $datalink)))) && !preg_match("/^Error\\:/i", $unprocessed_ipn_lines)) { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); $ccbill["s2member_log"][] = "Storing new DataLink IPNs into a Transient Queue."; $ccbill["s2member_log"][] = $datalink; $ccbill["s2member_log"][] = $unprocessed_ipn_lines; set_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"), trim(trim(get_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"))) . "\n" . $unprocessed_ipn_lines), 31556926); } else { if (!preg_match("/^Error\\:/i", $unprocessed_ipn_lines)) { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); $ccbill["s2member_log"][] = "No new Datalink IPNs at this time: " . date("D M j, Y g:i:s a T"); $ccbill["s2member_log"][] = $datalink; $ccbill["s2member_log"][] = $unprocessed_ipn_lines; } else { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); $ccbill["s2member_log"][] = "Recording DataLink error at: " . date("D M j, Y g:i:s a T"); $ccbill["s2member_log"][] = "Recording server IP address: " . $_SERVER["SERVER_ADDR"]; $ccbill["s2member_log"][] = $datalink; $ccbill["s2member_log"][] = $unprocessed_ipn_lines; } } $logt = c_ws_plugin__s2member_utilities::time_details(); $logv = c_ws_plugin__s2member_utilities::ver_details(); $logm = c_ws_plugin__s2member_utilities::mem_details(); $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"]; $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4; $log2 = is_multisite() && !is_main_site() ? "ccbill-dl-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "ccbill-dl.log"; if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) { if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) { if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) { file_put_contents($logs_dir . "/" . $log2, "LOG ENTRY: " . $logt . "\n" . $logv . "\n" . $logm . "\n" . $log4 . "\n" . c_ws_plugin__s2member_utils_logs::conceal_private_info(var_export($ccbill, true)) . "\n\n", FILE_APPEND); } } } } else { if ($unprocessed_ipn_lines = trim(get_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns")))) { $per_process = apply_filters("ws_plugin__s2member_pro_ccbill_datalink_ipns_per_process", $vars["per_process"], get_defined_vars()); foreach ($unprocessed_lines = preg_split("/[\r\n]+/", $unprocessed_ipn_lines) as $line => $unprocessed_line) { unset($ccbill, $processing, $processed, $ipn, $log4, $_log4, $log2, $logs_dir); if (($unprocessed_line = trim($unprocessed_line)) && ($counter = (int) $counter + 1)) { $ccbill["s2member_log"][] = "DataLink IPN processed on: " . date("D M j, Y g:i:s a T"); $ccbill["dl_ipn"] = c_ws_plugin__s2member_utils_strings::trim_dq_deep(preg_split("/\",\"/", $unprocessed_line)); if (is_array($ccbill["dl_ipn_signup_vars"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(false, $ccbill["dl_ipn"][3]))) { if (preg_match("/^REBILL\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill transaction identified as (SUBSCRIPTION PAYMENT)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal processor as txn_type (subscr_payment)."; $ccbill["s2member_log"][] = "Please check PayPal IPN logs for further processing details."; $processing = $processed = true; $ipn = array(); $ipn["txn_type"] = "subscr_payment"; $ipn["subscr_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; $ipn["txn_id"] = $ccbill["dl_ipn"][5]; $ipn["mc_gross"] = number_format($ccbill["dl_ipn"][6], 2, ".", ""); $ipn["mc_currency"] = strtoupper("USD"); $ipn["tax"] = number_format("0.00", 2, ".", ""); $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; $ipn["s2member_paypal_proxy"] = "ccbill"; $ipn["s2member_paypal_proxy_use"] = "standard-emails"; $ipn["s2member_paypal_proxy_verification"] = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen(); c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1"), $ipn, array("timeout" => 20)); } else { if (preg_match("/^CANCELLATION\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill transaction identified as (SUBSCRIPTION CANCELLATION)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal processor as txn_type (subscr_cancel)."; $ccbill["s2member_log"][] = "Please check PayPal IPN logs for further processing details."; $processing = $processed = true; $ipn = array(); $ipn["txn_type"] = "subscr_cancel"; $ipn["subscr_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; $ipn["period1"] = $ccbill["dl_ipn_signup_vars"]["period1"]; $ipn["period3"] = $ccbill["dl_ipn_signup_vars"]["period3"]; $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; $ipn["s2member_paypal_proxy"] = "ccbill"; $ipn["s2member_paypal_proxy_use"] = "standard-emails"; $ipn["s2member_paypal_proxy_verification"] = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen(); c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1"), $ipn, array("timeout" => 20)); } else { if (preg_match("/^EXPIRE\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill transaction identified as (SUBSCRIPTION EXPIRATION)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal processor as txn_type (subscr_eot)."; $ccbill["s2member_log"][] = "Please check PayPal IPN logs for further processing details."; $processing = $processed = true; $ipn = array(); $ipn["txn_type"] = "subscr_eot"; $ipn["subscr_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; $ipn["period1"] = $ccbill["dl_ipn_signup_vars"]["period1"]; $ipn["period3"] = $ccbill["dl_ipn_signup_vars"]["period3"]; $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; $ipn["s2member_paypal_proxy"] = "ccbill"; $ipn["s2member_paypal_proxy_use"] = "standard-emails"; $ipn["s2member_paypal_proxy_verification"] = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen(); c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1"), $ipn, array("timeout" => 20)); } else { if (preg_match("/^(REFUND|CHARGEBACK)\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill transaction identified as (REFUND|CHARGEBACK)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal processor as payment_status (refunded|reversed)."; $ccbill["s2member_log"][] = "Please check PayPal IPN logs for further processing details."; $processing = $processed = true; $ipn = array(); $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; $ipn["parent_txn_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; $ipn["payment_status"] = preg_match("/^CHARGEBACK\$/i", $ccbill["dl_ipn"][0]) ? "reversed" : "refunded"; $ipn["mc_fee"] = "-" . number_format("0.00", 2, ".", ""); $ipn["mc_gross"] = "-" . number_format($ccbill["dl_ipn"][5], 2, ".", ""); $ipn["mc_currency"] = strtoupper("USD"); $ipn["tax"] = "-" . number_format("0.00", 2, ".", ""); $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; $ipn["s2member_paypal_proxy"] = "ccbill"; $ipn["s2member_paypal_proxy_use"] = "standard-emails"; $ipn["s2member_paypal_proxy_verification"] = c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen(); c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1"), $ipn, array("timeout" => 20)); } else { if (!$processed) { // Here we add a message to the logs indicating the IPN was ignored; no action taken. $ccbill["s2member_log"][] = "Ignoring this DataLink IPN. It does NOT require any action on the part of s2Member."; } } } } } } else { if (!$processed) { // Here we add a message to the logs indicating that no IPN vars are available. $ccbill["s2member_log"][] = "Ignoring this DataLink IPN. No IPN signup vars for Subscr. ID: " . $ccbill["dl_ipn"][3] . "."; } } $logt = c_ws_plugin__s2member_utilities::time_details(); $logv = c_ws_plugin__s2member_utilities::ver_details(); $logm = c_ws_plugin__s2member_utilities::mem_details(); $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"]; $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4; $log2 = is_multisite() && !is_main_site() ? "ccbill-dl-ipn-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "ccbill-dl-ipn.log"; if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) { if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) { if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) { file_put_contents($logs_dir . "/" . $log2, "LOG ENTRY: " . $logt . "\n" . $logv . "\n" . $logm . "\n" . $log4 . "\n" . c_ws_plugin__s2member_utils_logs::conceal_private_info(var_export($ccbill, true)) . "\n\n", FILE_APPEND); } } } } unset($unprocessed_lines[$line]); // Remove this line and update the list of unprocessed IPN lines. set_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"), implode("\n", $unprocessed_lines), 31556926); if ($counter >= $per_process) { break; } // Break the loop now. } } } } return; }
/** * Connect to and process DataLink information for ccBill®. * * s2Member's Auto EOT System must be enabled for this to work properly. * * If you have a HUGE userbase, increase the max IPNs per process. * But NOTE, this runs ``$per_process`` *( per Blog )* on a Multisite Network. * To increase, use: ``add_filter ("ws_plugin__s2member_pro_ccbill_datalink_ipns_per_process");``. * * @package s2Member\ccBill * @since 1.5 * * @attaches-to ``add_action("ws_plugin__s2member_after_auto_eot_system");`` * * @param array $vars Expects an array of defined variables passed in by the Action Hook. * @return null */ public static function ccbill_datalink($vars = FALSE) { global $wpdb; /* Need global DB obj. */ global $current_site, $current_blog; /* For Multisite support. */ /**/ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_id"]) { $datalink = "https://datalink.ccbill.com/data/main.cgi"; /* DataLink service. */ /**/ if (!($last = get_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"))) || $last < time() - 86400) { $start = $last && $last >= time() - (86400 + 43200) ? $last : time() - 86400; /* Don't let $start time be less than 1 day + 12 hours ago. */ $end = $last = $start + 86400; /* Sets $end time to exactly 1 day later. This also sets $last time; which is recorded later in this routine. */ /**/ $qvrs = array("startTime" => date("YmdHis", $start), "endTime" => date("YmdHis", $end), "transactionTypes" => "EXPIRE,REBILL,REFUND,CHARGEBACK", "clientAccnum" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_id"], "clientSubacc" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_client_sid"], "username" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_dl_user"], "password" => $GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_ccbill_dl_pass"]); /**/ if (($unprocessed_ipn_lines = trim(c_ws_plugin__s2member_utils_urls::remote($datalink = add_query_arg(urlencode_deep($qvrs), $datalink)))) && !preg_match("/^Error\\:/i", $unprocessed_ipn_lines)) { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); /**/ set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); /**/ $ccbill["s2member_log"][] = "Storing new DataLink IPNs into a Transient Queue."; $ccbill["s2member_log"][] = $datalink; /* Record the full DataLink URL as well. */ $ccbill["s2member_log"][] = $unprocessed_ipn_lines; /* Record list in log. */ /**/ set_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"), trim(trim(get_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"))) . "\n" . $unprocessed_ipn_lines), 31556926); } else { if (!preg_match("/^Error\\:/i", $unprocessed_ipn_lines)) { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); /**/ set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); /**/ $ccbill["s2member_log"][] = "No new Datalink IPNs at this time: " . date("D M j, Y g:i:s a T"); $ccbill["s2member_log"][] = $datalink; /* Record the full DataLink URL as well. */ $ccbill["s2member_log"][] = $unprocessed_ipn_lines; /* Log this; just in case. */ } else { $ccbill["s2member_log"][] = "Storing last DataLink time: " . date("D M j, Y g:i:s a T", $last); /**/ set_transient("s2m_" . md5("s2member_pro_ccbill_last_datalink"), $last, 31556926); /**/ $ccbill["s2member_log"][] = "Recording DataLink error at: " . date("D M j, Y g:i:s a T"); $ccbill["s2member_log"][] = "Recording server IP address: " . $_SERVER["SERVER_ADDR"]; $ccbill["s2member_log"][] = $datalink; /* Record the full DataLink URL as well. */ $ccbill["s2member_log"][] = $unprocessed_ipn_lines; /* Log error mesg. */ } } /**/ $logv = c_ws_plugin__s2member_utilities::ver_details(); $logm = c_ws_plugin__s2member_utilities::mem_details(); $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"]; $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4; $log2 = is_multisite() && !is_main_site() ? "ccbill-dl-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "ccbill-dl.log"; /**/ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) { if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) { if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) { file_put_contents($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export($ccbill, true) . "\n\n", FILE_APPEND); } } } } else { if ($unprocessed_ipn_lines = trim(get_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns")))) { $per_process = apply_filters("ws_plugin__s2member_pro_ccbill_datalink_ipns_per_process", $vars["per_process"], get_defined_vars()); /**/ foreach ($unprocessed_lines = preg_split("/[\r\n]+/", $unprocessed_ipn_lines) as $line => $unprocessed_line) { unset($ccbill, $processing, $processed, $ipn, $ipn_q, $log4, $_log4, $log2, $logs_dir); /* Unset/reset these variables each pass. */ /**/ if (($unprocessed_line = trim($unprocessed_line)) && ($counter = (int) $counter + 1)) { $ccbill["s2member_log"][] = "DataLink IPN processed on: " . date("D M j, Y g:i:s a T"); /**/ $ccbill["dl_ipn"] = c_ws_plugin__s2member_utils_strings::trim_dq_deep(preg_split("/\",\"/", $unprocessed_line)); /**/ if (is_array($ccbill["dl_ipn_signup_vars"] = c_ws_plugin__s2member_utils_users::get_user_ipn_signup_vars(false, $ccbill["dl_ipn"][3]))) { if (preg_match("/^REBILL\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill® transaction identified as (SUBSCRIPTION PAYMENT)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal® processor as txn_type (subscr_payment)."; $ccbill["s2member_log"][] = "Please check PayPal® IPN logs for further processing details."; /**/ $processing = $processed = true; $ipn = array(); /* Reset. */ /**/ $ipn["txn_type"] = "subscr_payment"; $ipn["subscr_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; /**/ $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; /**/ $ipn["txn_id"] = $ccbill["dl_ipn"][5]; /* Unique transaction ID. */ /**/ $ipn["mc_gross"] = number_format($ccbill["dl_ipn"][6], 2, ".", ""); $ipn["mc_currency"] = strtoupper("USD"); /* DataLink uses USD. */ $ipn["tax"] = number_format("0.00", 2, ".", ""); /**/ $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; /**/ $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; /**/ $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; /**/ $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; /**/ $ipn_q = "&s2member_paypal_proxy=ccbill&s2member_paypal_proxy_use=standard-emails"; $ipn_q .= "&s2member_paypal_proxy_verification=" . urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()); /**/ c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1" . $ipn_q), $ipn, array("timeout" => 20)); } else { if (preg_match("/^EXPIRE\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill® transaction identified as (SUBSCRIPTION EXPIRATION)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal® processor as txn_type (subscr_eot)."; $ccbill["s2member_log"][] = "Please check PayPal® IPN logs for further processing details."; /**/ $processing = $processed = true; $ipn = array(); /* Reset. */ /**/ $ipn["txn_type"] = "subscr_eot"; $ipn["subscr_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; /**/ $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; /**/ $ipn["period1"] = $ccbill["dl_ipn_signup_vars"]["period1"]; $ipn["period3"] = $ccbill["dl_ipn_signup_vars"]["period3"]; /**/ $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; /**/ $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; /**/ $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; /**/ $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; /**/ $ipn_q = "&s2member_paypal_proxy=ccbill&s2member_paypal_proxy_use=standard-emails"; $ipn_q .= "&s2member_paypal_proxy_verification=" . urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()); /**/ c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1" . $ipn_q), $ipn, array("timeout" => 20)); } else { if (preg_match("/^(REFUND|CHARGEBACK)\$/i", $ccbill["dl_ipn"][0])) { $ccbill["s2member_log"][] = "ccBill® transaction identified as (REFUND|CHARGEBACK)."; $ccbill["s2member_log"][] = "IPN reformulated. Piping through s2Member's core/standard PayPal® processor as payment_status (refunded|reversed)."; $ccbill["s2member_log"][] = "Please check PayPal® IPN logs for further processing details."; /**/ $processing = $processed = true; $ipn = array(); /* Reset. */ /**/ $ipn["custom"] = $ccbill["dl_ipn_signup_vars"]["custom"]; /**/ $ipn["parent_txn_id"] = $ccbill["dl_ipn_signup_vars"]["subscr_id"]; /**/ $ipn["payment_status"] = preg_match("/^CHARGEBACK\$/i", $ccbill["dl_ipn"][0]) ? "reversed" : "refunded"; $ipn["mc_fee"] = "-" . number_format("0.00", 2, ".", ""); $ipn["mc_gross"] = "-" . number_format($ccbill["dl_ipn"][5], 2, ".", ""); $ipn["mc_currency"] = strtoupper("USD"); /* DataLink uses USD. */ $ipn["tax"] = "-" . number_format("0.00", 2, ".", ""); /**/ $ipn["payer_email"] = $ccbill["dl_ipn_signup_vars"]["payer_email"]; $ipn["first_name"] = $ccbill["dl_ipn_signup_vars"]["first_name"]; $ipn["last_name"] = $ccbill["dl_ipn_signup_vars"]["last_name"]; /**/ $ipn["option_name1"] = $ccbill["dl_ipn_signup_vars"]["option_name1"]; $ipn["option_selection1"] = $ccbill["dl_ipn_signup_vars"]["option_selection1"]; /**/ $ipn["option_name2"] = $ccbill["dl_ipn_signup_vars"]["option_name2"]; $ipn["option_selection2"] = $ccbill["dl_ipn_signup_vars"]["option_selection2"]; /**/ $ipn["item_number"] = $ccbill["dl_ipn_signup_vars"]["item_number"]; $ipn["item_name"] = $ccbill["dl_ipn_signup_vars"]["item_name"]; /**/ $ipn_q = "&s2member_paypal_proxy=ccbill&s2member_paypal_proxy_use=standard-emails"; $ipn_q .= "&s2member_paypal_proxy_verification=" . urlencode(c_ws_plugin__s2member_paypal_utilities::paypal_proxy_key_gen()); /**/ c_ws_plugin__s2member_utils_urls::remote(site_url("/?s2member_paypal_notify=1" . $ipn_q), $ipn, array("timeout" => 20)); } else { if (!$processed) { /* Here we add a message to the logs indicating the IPN was ignored; no action taken. */ $ccbill["s2member_log"][] = "Ignoring this DataLink IPN. It does NOT require any action on the part of s2Member."; } } } } } else { if (!$processed) { /* Here we add a message to the logs indicating that no IPN vars are available. */ $ccbill["s2member_log"][] = "Ignoring this DataLink IPN. No IPN signup vars for Subscr. ID: " . $ccbill["dl_ipn"][3] . "."; } } /**/ $logv = c_ws_plugin__s2member_utilities::ver_details(); $logm = c_ws_plugin__s2member_utilities::mem_details(); $log4 = $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] . "\nUser-Agent: " . $_SERVER["HTTP_USER_AGENT"]; $log4 = is_multisite() && !is_main_site() ? ($_log4 = $current_blog->domain . $current_blog->path) . "\n" . $log4 : $log4; $log2 = is_multisite() && !is_main_site() ? "ccbill-dl-ipn-4-" . trim(preg_replace("/[^a-z0-9]/i", "-", $_log4), "-") . ".log" : "ccbill-dl-ipn.log"; /**/ if ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["gateway_debug_logs"]) { if (is_dir($logs_dir = $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["logs_dir"])) { if (is_writable($logs_dir) && c_ws_plugin__s2member_utils_logs::archive_oversize_log_files()) { file_put_contents($logs_dir . "/" . $log2, $logv . "\n" . $logm . "\n" . $log4 . "\n" . var_export($ccbill, true) . "\n\n", FILE_APPEND); } } } } /**/ unset($unprocessed_lines[$line]); /* Remove this line and update the list of unprocessed IPN lines. */ set_transient("s2m_" . md5("s2member_pro_ccbill_datalink_ipns"), implode("\n", $unprocessed_lines), 31556926); /**/ if ($counter >= $per_process) { /* Only this many. */ break; } /* Break the loop now. */ } } } } /**/ return; /* Return for uniformity. */ }