/**
 * Process PayPal IPN
 *
 * @access      private
 * @since       1.0 
 * @return      void
*/
function edd_process_paypal_ipn()
{
    global $edd_options;
    // check the request method is POST
    if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'POST') {
        return;
    }
    // set initial post data to false
    $post_data = false;
    // fallback just in case post_max_size is lower than needed
    if (ini_get('allow_url_fopen')) {
        $post_data = file_get_contents('php://input');
    } else {
        // if allow_url_fopen is not enabled, then make sure that post_max_size is large enough
        ini_set('post_max_size', '12M');
    }
    // start the encoded data collection with notification command
    $encoded_data = 'cmd=_notify-validate';
    // get current arg separator
    $arg_separator = edd_get_php_arg_separator_output();
    // verify there is a post_data
    if ($post_data || strlen($post_data) > 0) {
        // append the data
        $encoded_data .= $arg_separator . $post_data;
    } else {
        // check if POST is empty
        if (empty($_POST)) {
            // nothing to do
            return;
        } else {
            // loop trough each POST
            foreach ($_POST as $key => $value) {
                // encode the value and append the data
                $encoded_data .= $arg_separator . "{$key}=" . urlencode($value);
            }
        }
    }
    // convert collected post data to an array
    parse_str($encoded_data, $encoded_data_array);
    // get the PayPal redirect uri
    $paypal_redirect = edd_get_paypal_redirect(true);
    $remote_post_vars = array('method' => 'POST', 'timeout' => 45, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => $encoded_data_array);
    // get response
    $api_response = wp_remote_post(edd_get_paypal_redirect(), $remote_post_vars);
    if (is_wp_error($api_response)) {
        return;
    }
    // something went wrong
    if ($api_response['body'] !== 'VERIFIED' && !isset($edd_options['disable_paypal_verification'])) {
        return;
    }
    // response not okay
    // convert collected post data to an array
    parse_str($post_data, $post_data_array);
    // check if $post_data_array has been populated
    if (!is_array($encoded_data_array) && !empty($encoded_data_array)) {
        return;
    }
    // collect payment details
    $payment_id = $encoded_data_array['custom'];
    $purchase_key = $encoded_data_array['item_number'];
    $paypal_amount = $encoded_data_array['mc_gross'];
    $payment_status = $encoded_data_array['payment_status'];
    $currency_code = strtolower($encoded_data_array['mc_currency']);
    // retrieve the meta info for this payment
    $payment_meta = get_post_meta($payment_id, '_edd_payment_meta', true);
    $payment_amount = edd_format_amount($payment_meta['amount']);
    // verify details
    if ($currency_code != strtolower($edd_options['currency'])) {
        // the currency code is invalid
        return;
    }
    if (number_format((double) $paypal_amount, 2) != $payment_amount) {
        // the prices don't match
        //return;
    }
    if ($purchase_key != $payment_meta['key']) {
        // purchase keys don't match
        return;
    }
    if (isset($encoded_data_array['txn_type']) && $encoded_data_array['txn_type'] == 'web_accept') {
        $status = strtolower($payment_status);
        if ($status == 'completed' || edd_is_test_mode()) {
            edd_update_payment_status($payment_id, 'publish');
        }
    }
}
/**
 * Process PayPal IPN
 *
 * @since 1.0
 * @return void
 */
function edd_process_paypal_ipn()
{
    // Check the request method is POST
    if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'POST') {
        return;
    }
    // Set initial post data to empty string
    $post_data = '';
    // Fallback just in case post_max_size is lower than needed
    if (ini_get('allow_url_fopen')) {
        $post_data = file_get_contents('php://input');
    } else {
        // If allow_url_fopen is not enabled, then make sure that post_max_size is large enough
        ini_set('post_max_size', '12M');
    }
    // Start the encoded data collection with notification command
    $encoded_data = 'cmd=_notify-validate';
    // Get current arg separator
    $arg_separator = edd_get_php_arg_separator_output();
    // Verify there is a post_data
    if ($post_data || strlen($post_data) > 0) {
        // Append the data
        $encoded_data .= $arg_separator . $post_data;
    } else {
        // Check if POST is empty
        if (empty($_POST)) {
            // Nothing to do
            return;
        } else {
            // Loop through each POST
            foreach ($_POST as $key => $value) {
                // Encode the value and append the data
                $encoded_data .= $arg_separator . "{$key}=" . urlencode($value);
            }
        }
    }
    // Convert collected post data to an array
    parse_str($encoded_data, $encoded_data_array);
    // Get the PayPal redirect uri
    $paypal_redirect = edd_get_paypal_redirect(true);
    if (!edd_get_option('disable_paypal_verification')) {
        // Validate the IPN
        $remote_post_vars = array('method' => 'POST', 'timeout' => 45, 'redirection' => 5, 'httpversion' => '1.1', 'blocking' => true, 'headers' => array('host' => 'www.paypal.com', 'connection' => 'close', 'content-type' => 'application/x-www-form-urlencoded', 'post' => '/cgi-bin/webscr HTTP/1.1'), 'sslverify' => false, 'body' => $encoded_data_array);
        // Get response
        $api_response = wp_remote_post(edd_get_paypal_redirect(), $remote_post_vars);
        if (is_wp_error($api_response)) {
            edd_record_gateway_error(__('IPN Error', 'edd'), sprintf(__('Invalid IPN verification response. IPN data: %s', 'edd'), json_encode($api_response)));
            return;
            // Something went wrong
        }
        if ($api_response['body'] !== 'VERIFIED' && edd_get_option('disable_paypal_verification', false)) {
            edd_record_gateway_error(__('IPN Error', 'edd'), sprintf(__('Invalid IPN verification response. IPN data: %s', 'edd'), json_encode($api_response)));
            return;
            // Response not okay
        }
    }
    // Check if $post_data_array has been populated
    if (!is_array($encoded_data_array) && !empty($encoded_data_array)) {
        return;
    }
    $defaults = array('txn_type' => '', 'payment_status' => '');
    $encoded_data_array = wp_parse_args($encoded_data_array, $defaults);
    $payment_id = isset($encoded_data_array['custom']) ? absint($encoded_data_array['custom']) : 0;
    if (has_action('edd_paypal_' . $encoded_data_array['txn_type'])) {
        // Allow PayPal IPN types to be processed separately
        do_action('edd_paypal_' . $encoded_data_array['txn_type'], $encoded_data_array, $payment_id);
    } else {
        // Fallback to web accept just in case the txn_type isn't present
        do_action('edd_paypal_web_accept', $encoded_data_array, $payment_id);
    }
    exit;
}
/**
 * Process PayPal IPN
 *
 * @access      private
 * @since       1.0
 * @return      void
*/
function edd_process_paypal_ipn()
{
    global $edd_options;
    // check the request method is POST
    if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'POST') {
        return;
    }
    // set initial post data to false
    $post_data = false;
    // fallback just in case post_max_size is lower than needed
    if (ini_get('allow_url_fopen')) {
        $post_data = file_get_contents('php://input');
    } else {
        // if allow_url_fopen is not enabled, then make sure that post_max_size is large enough
        ini_set('post_max_size', '12M');
    }
    // start the encoded data collection with notification command
    $encoded_data = 'cmd=_notify-validate';
    // get current arg separator
    $arg_separator = edd_get_php_arg_separator_output();
    // verify there is a post_data
    if ($post_data || strlen($post_data) > 0) {
        // append the data
        $encoded_data .= $arg_separator . $post_data;
    } else {
        // check if POST is empty
        if (empty($_POST)) {
            // nothing to do
            return;
        } else {
            // loop trough each POST
            foreach ($_POST as $key => $value) {
                // encode the value and append the data
                $encoded_data .= $arg_separator . "{$key}=" . urlencode($value);
            }
        }
    }
    // convert collected post data to an array
    parse_str($encoded_data, $encoded_data_array);
    // get the PayPal redirect uri
    $paypal_redirect = edd_get_paypal_redirect(true);
    $remote_post_vars = array('method' => 'POST', 'timeout' => 45, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'sslverify' => false, 'body' => $encoded_data_array);
    // get response
    $api_response = wp_remote_post(edd_get_paypal_redirect(), $remote_post_vars);
    if (is_wp_error($api_response)) {
        edd_record_gateway_error(__('IPN Error', 'edd'), sprintf(__('Invalid IPN verification response. IPN data: ', 'edd'), json_encode($api_response)));
        return;
        // something went wrong
    }
    if ($api_response['body'] !== 'VERIFIED' && !isset($edd_options['disable_paypal_verification'])) {
        edd_record_gateway_error(__('IPN Error', 'edd'), sprintf(__('Invalid IPN verification response. IPN data: ', 'edd'), json_encode($api_response)));
        return;
        // response not okay
    }
    // check if $post_data_array has been populated
    if (!is_array($encoded_data_array) && !empty($encoded_data_array)) {
        return;
    }
    if (has_action('edd_paypal_' . $encoded_data_array['txn_type'])) {
        // allow PayPal IPN types to be processed separately
        do_action('edd_paypal_' . $encoded_data_array['txn_type'], $encoded_data_array);
    } else {
        // fallback to web accept just in case the txn_type isn't present
        do_action('edd_paypal_web_accept', $encoded_data_array);
    }
}