/**
  * Calls upon Authorize.Net® ARB, 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_arb_response($post_vars = FALSE)
 {
     global $current_site, $current_blog;
     /* For Multisite support. */
     /**/
     $url = "https://" . ($GLOBALS["WS_PLUGIN__"]["s2member"]["o"]["pro_authnet_sandbox"] ? "apitest.authorize.net" : "api.authorize.net") . "/xml/v1/request.api";
     /**/
     $post_vars = is_array($post_vars) ? $post_vars : array();
     /* Must be in array format. */
     /**/
     $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_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"]);
     /**/
     $trial = !empty($post_vars["x_trial_occurrences"]) ? true : false;
     /* Indicates existence of trial. */
     /**/
     if (!empty($post_vars["x_method"]) && $post_vars["x_method"] === "create") {
         $xml = '<?xml version="1.0" encoding="utf-8"?>';
         /**/
         $xml .= '<ARBCreateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">';
         /**/
         $xml .= '<merchantAuthentication>';
         $xml .= '<name>' . esc_html($post_vars["x_login"]) . '</name>';
         $xml .= '<transactionKey>' . esc_html($post_vars["x_tran_key"]) . '</transactionKey>';
         $xml .= '</merchantAuthentication>';
         /**/
         $xml .= '<refId>' . esc_html($post_vars["x_invoice_num"]) . '</refId>';
         /**/
         $xml .= '<subscription>';
         /**/
         $xml .= '<name>' . esc_html($_SERVER["HTTP_HOST"]) . '</name>';
         /**/
         $xml .= '<paymentSchedule>';
         $xml .= '<interval>';
         $xml .= '<length>' . esc_html($post_vars["x_length"]) . '</length>';
         $xml .= '<unit>' . esc_html($post_vars["x_unit"]) . '</unit>';
         $xml .= '</interval>';
         $xml .= '<startDate>' . esc_html($post_vars["x_start_date"]) . '</startDate>';
         $xml .= '<totalOccurrences>' . esc_html($post_vars["x_total_occurrences"]) . '</totalOccurrences>';
         $xml .= $trial ? '<trialOccurrences>' . esc_html($post_vars["x_trial_occurrences"]) . '</trialOccurrences>' : '';
         $xml .= '</paymentSchedule>';
         /**/
         $xml .= '<amount>' . esc_html($post_vars["x_amount"]) . '</amount>';
         $xml .= $trial ? '<trialAmount>' . esc_html($post_vars["x_trial_amount"]) . '</trialAmount>' : '';
         /**/
         $xml .= '<payment>';
         $xml .= '<creditCard>';
         $xml .= '<cardNumber>' . esc_html($post_vars["x_card_num"]) . '</cardNumber>';
         $xml .= '<expirationDate>' . esc_html($post_vars["x_exp_date"]) . '</expirationDate>';
         $xml .= '<cardCode>' . esc_html($post_vars["x_card_code"]) . '</cardCode>';
         $xml .= '</creditCard>';
         $xml .= '</payment>';
         /**/
         $xml .= '<order>';
         $xml .= '<invoiceNumber>' . esc_html($post_vars["x_invoice_num"]) . '</invoiceNumber>';
         $xml .= '<description>' . esc_html($post_vars["x_description"]) . '</description>';
         $xml .= '</order>';
         /**/
         $xml .= '<customer>';
         $xml .= '<email>' . esc_html($post_vars["x_email"]) . '</email>';
         $xml .= '</customer>';
         /**/
         $xml .= '<billTo>';
         $xml .= '<firstName>' . esc_html($post_vars["x_first_name"]) . '</firstName>';
         $xml .= '<lastName>' . esc_html($post_vars["x_last_name"]) . '</lastName>';
         $xml .= '<address>' . esc_html($post_vars["x_address"]) . '</address>';
         $xml .= '<city>' . esc_html($post_vars["x_city"]) . '</city>';
         $xml .= '<state>' . esc_html($post_vars["x_state"]) . '</state>';
         $xml .= '<zip>' . esc_html($post_vars["x_zip"]) . '</zip>';
         $xml .= '<country>' . esc_html($post_vars["x_country"]) . '</country>';
         $xml .= '</billTo>';
         /**/
         $xml .= '</subscription>';
         /**/
         $xml .= '</ARBCreateSubscriptionRequest>';
     } else {
         if (!empty($post_vars["x_method"]) && $post_vars["x_method"] === "update") {
             $xml = '<?xml version="1.0" encoding="utf-8"?>';
             /**/
             $xml .= '<ARBUpdateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">';
             /**/
             $xml .= '<merchantAuthentication>';
             $xml .= '<name>' . esc_html($post_vars["x_login"]) . '</name>';
             $xml .= '<transactionKey>' . esc_html($post_vars["x_tran_key"]) . '</transactionKey>';
             $xml .= '</merchantAuthentication>';
             /**/
             $xml .= '<subscriptionId>' . esc_html($post_vars["x_subscription_id"]) . '</subscriptionId>';
             /**/
             $xml .= '<subscription>';
             /**/
             $xml .= '<payment>';
             $xml .= '<creditCard>';
             $xml .= '<cardNumber>' . esc_html($post_vars["x_card_num"]) . '</cardNumber>';
             $xml .= '<expirationDate>' . esc_html($post_vars["x_exp_date"]) . '</expirationDate>';
             $xml .= '<cardCode>' . esc_html($post_vars["x_card_code"]) . '</cardCode>';
             $xml .= '</creditCard>';
             $xml .= '</payment>';
             /**/
             $xml .= '<customer>';
             $xml .= '<email>' . esc_html($post_vars["x_email"]) . '</email>';
             $xml .= '</customer>';
             /**/
             $xml .= '<billTo>';
             $xml .= '<firstName>' . esc_html($post_vars["x_first_name"]) . '</firstName>';
             $xml .= '<lastName>' . esc_html($post_vars["x_last_name"]) . '</lastName>';
             $xml .= '<address>' . esc_html($post_vars["x_address"]) . '</address>';
             $xml .= '<city>' . esc_html($post_vars["x_city"]) . '</city>';
             $xml .= '<state>' . esc_html($post_vars["x_state"]) . '</state>';
             $xml .= '<zip>' . esc_html($post_vars["x_zip"]) . '</zip>';
             $xml .= '<country>' . esc_html($post_vars["x_country"]) . '</country>';
             $xml .= '</billTo>';
             /**/
             $xml .= '</subscription>';
             /**/
             $xml .= '</ARBUpdateSubscriptionRequest>';
         } else {
             if (!empty($post_vars["x_method"]) && $post_vars["x_method"] === "status") {
                 $xml = '<?xml version="1.0" encoding="utf-8"?>';
                 /**/
                 $xml .= '<ARBGetSubscriptionStatusRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">';
                 /**/
                 $xml .= '<merchantAuthentication>';
                 $xml .= '<name>' . esc_html($post_vars["x_login"]) . '</name>';
                 $xml .= '<transactionKey>' . esc_html($post_vars["x_tran_key"]) . '</transactionKey>';
                 $xml .= '</merchantAuthentication>';
                 /**/
                 $xml .= '<subscriptionId>' . esc_html($post_vars["x_subscription_id"]) . '</subscriptionId>';
                 /**/
                 $xml .= '</ARBGetSubscriptionStatusRequest>';
             } else {
                 if (!empty($post_vars["x_method"]) && $post_vars["x_method"] === "cancel") {
                     $xml = '<?xml version="1.0" encoding="utf-8"?>';
                     /**/
                     $xml .= '<ARBCancelSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">';
                     /**/
                     $xml .= '<merchantAuthentication>';
                     $xml .= '<name>' . esc_html($post_vars["x_login"]) . '</name>';
                     $xml .= '<transactionKey>' . esc_html($post_vars["x_tran_key"]) . '</transactionKey>';
                     $xml .= '</merchantAuthentication>';
                     /**/
                     $xml .= '<subscriptionId>' . esc_html($post_vars["x_subscription_id"]) . '</subscriptionId>';
                     /**/
                     $xml .= '</ARBCancelSubscriptionRequest>';
                 }
             }
         }
     }
     /**/
     $req["headers"]["Accept"] = "application/xml; charset=UTF-8";
     $req["headers"]["Content-Type"] = "application/xml; charset=UTF-8";
     /**/
     $input_time = date("D M j, Y g:i:s a T");
     /* Record input time for logging. */
     /**/
     $xml = trim(c_ws_plugin__s2member_utils_urls::remote($url, $xml, array_merge($req, array("timeout" => 20))));
     /**/
     $output_time = date("D M j, Y g:i:s a T");
     /* Now record after output time. */
     /**/
     $response = c_ws_plugin__s2member_pro_authnet_utilities::_authnet_parse_arb_response($xml);
     /**/
     if (empty($response["response_code"]) || $response["response_code"] !== "I00001") {
         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_arb_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" . $xml . "\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_arb_response", c_ws_plugin__s2member_pro_authnet_utilities::_authnet_arb_response_filters($response), get_defined_vars());
 }