/**
  * Process PayPal IPN
  *
  * @since 2.1
  */
 public function process_webhooks()
 {
     if (!isset($_GET['listener']) || strtoupper($_GET['listener']) != 'IPN') {
         return;
     }
     global $rcp_options;
     nocache_headers();
     if (!class_exists('IpnListener')) {
         // instantiate the IpnListener class
         include RCP_PLUGIN_DIR . 'includes/gateways/paypal/paypal-ipnlistener.php';
     }
     $listener = new IpnListener();
     $verified = false;
     if ($this->test_mode) {
         $listener->use_sandbox = true;
     }
     /*
     if( isset( $rcp_options['ssl'] ) ) {
     	$listener->use_ssl = true;
     } else {
     	$listener->use_ssl = false;
     }
     */
     //To post using the fsockopen() function rather than cURL, use:
     if (isset($rcp_options['disable_curl'])) {
         $listener->use_curl = false;
     }
     try {
         $listener->requirePostMethod();
         $verified = $listener->processIpn();
     } catch (Exception $e) {
         status_header(402);
         //die( 'IPN exception: ' . $e->getMessage() );
     }
     /*
     The processIpn() method returned true if the IPN was "VERIFIED" and false if it
     was "INVALID".
     */
     if ($verified || isset($_POST['verification_override']) || ($this->test_mode || isset($rcp_options['disable_ipn_verify']))) {
         status_header(200);
         $user_id = 0;
         $posted = apply_filters('rcp_ipn_post', $_POST);
         // allow $_POST to be modified
         if (!empty($posted['custom']) && is_numeric($posted['custom'])) {
             $user_id = absint($posted['custom']);
         } else {
             if (!empty($posted['subscr_id'])) {
                 $user_id = rcp_get_member_id_from_profile_id($posted['subscr_id']);
             } else {
                 if (!empty($posted['payer_email'])) {
                     $user = get_user_by('email', $posted['payer_email']);
                     $user_id = $user ? $user->ID : false;
                 }
             }
         }
         $member = new RCP_Member($user_id);
         if (!$member || !$member->get_subscription_id()) {
             die('no member found');
         }
         if (!rcp_get_subscription_details($member->get_subscription_id())) {
             die('no subscription level found');
         }
         $subscription_name = $posted['item_name'];
         $subscription_key = $posted['item_number'];
         $amount = number_format((double) $posted['mc_gross'], 2);
         $amount2 = number_format((double) $posted['mc_amount3'], 2);
         $payment_status = $posted['payment_status'];
         $currency_code = $posted['mc_currency'];
         $subscription_price = number_format((double) rcp_get_subscription_price($member->get_subscription_id()), 2);
         // setup the payment info in an array for storage
         $payment_data = array('date' => date('Y-m-d g:i:s', strtotime($posted['payment_date'], current_time('timestamp'))), 'subscription' => $posted['item_name'], 'payment_type' => $posted['txn_type'], 'subscription_key' => $subscription_key, 'amount' => $amount, 'user_id' => $user_id, 'transaction_id' => $posted['txn_id']);
         do_action('rcp_valid_ipn', $payment_data, $user_id, $posted);
         if ($posted['txn_type'] == 'web_accept' || $posted['txn_type'] == 'subscr_payment') {
             // only check for an existing payment if this is a payment IPD request
             if (rcp_check_for_existing_payment($posted['txn_type'], $posted['payment_date'], $subscription_key)) {
                 $log_data = array('post_title' => __('Duplicate Payment', 'rcp'), 'post_content' => __('A duplicate payment was detected. The new payment was still recorded, so you may want to check into both payments.', 'rcp'), 'post_parent' => 0, 'log_type' => 'gateway_error');
                 $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id);
                 $log_entry = WP_Logging::insert_log($log_data, $log_meta);
                 die('duplicate IPN detected');
             }
             if (strtolower($currency_code) != strtolower($rcp_options['currency'])) {
                 // the currency code is invalid
                 $log_data = array('post_title' => __('Invalid Currency Code', 'rcp'), 'post_content' => sprintf(__('The currency code in an IPN request did not match the site currency code. Payment data: %s', 'rcp'), json_encode($payment_data)), 'post_parent' => 0, 'log_type' => 'gateway_error');
                 $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id);
                 $log_entry = WP_Logging::insert_log($log_data, $log_meta);
                 die('invalid currency code');
             }
         }
         if (isset($rcp_options['email_ipn_reports'])) {
             wp_mail(get_bloginfo('admin_email'), __('IPN report', 'rcp'), $listener->getTextReport());
         }
         /* now process the kind of subscription/payment */
         $rcp_payments = new RCP_Payments();
         // Subscriptions
         switch ($posted['txn_type']) {
             case "subscr_signup":
                 // when a new user signs up
                 // store the recurring payment ID
                 update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']);
                 $member->set_payment_profile_id($posted['subscr_id']);
                 do_action('rcp_ipn_subscr_signup', $user_id);
                 die('successful subscr_signup');
                 break;
             case "subscr_payment":
                 // when a user makes a recurring payment
                 update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']);
                 $member->set_payment_profile_id($posted['subscr_id']);
                 $member->renew(true);
                 // record this payment in the database
                 $rcp_payments->insert($payment_data);
                 do_action('rcp_ipn_subscr_payment', $user_id);
                 die('successful subscr_payment');
                 break;
             case "subscr_cancel":
                 // user is marked as cancelled but retains access until end of term
                 $member->set_status('cancelled');
                 // set the use to no longer be recurring
                 delete_user_meta($user_id, 'rcp_paypal_subscriber');
                 do_action('rcp_ipn_subscr_cancel', $user_id);
                 die('successful subscr_cancel');
                 break;
             case "subscr_failed":
                 do_action('rcp_ipn_subscr_failed');
                 die('successful subscr_failed');
                 break;
             case "subscr_eot":
                 // user's subscription has reached the end of its term
                 if ('cancelled' !== $member->get_status($user_id)) {
                     $member->set_status('expired');
                 }
                 do_action('rcp_ipn_subscr_eot', $user_id);
                 die('successful subscr_eot');
                 break;
             case "web_accept":
                 switch (strtolower($payment_status)) {
                     case 'completed':
                         // set this user to active
                         $member->renew();
                         $rcp_payments->insert($payment_data);
                         break;
                     case 'denied':
                     case 'expired':
                     case 'failed':
                     case 'voided':
                         $member->set_status('cancelled');
                         break;
                 }
                 die('successful web_accept');
                 break;
             case "cart":
             case "express_checkout":
             default:
                 break;
         }
     } else {
         if (isset($rcp_options['email_ipn_reports'])) {
             // an invalid IPN attempt was made. Send an email to the admin account to investigate
             wp_mail(get_bloginfo('admin_email'), __('Invalid IPN', 'rcp'), $listener->getTextReport());
         }
         status_header(400);
         die('invalid IPN');
     }
 }
Пример #2
0
function rcp_check_ipn()
{
    global $rcp_options;
    if (!class_exists('IpnListener')) {
        // instantiate the IpnListener class
        include RCP_PLUGIN_DIR . 'includes/gateways/paypal/ipnlistener.php';
    }
    $listener = new IpnListener();
    if (isset($rcp_options['sandbox'])) {
        $listener->use_sandbox = true;
    }
    if (isset($rcp_options['ssl'])) {
        $listener->use_ssl = true;
    } else {
        $listener->use_ssl = false;
    }
    //To post using the fsockopen() function rather than cURL, use:
    if (isset($rcp_options['disable_curl'])) {
        $listener->use_curl = false;
    }
    try {
        $listener->requirePostMethod();
        $verified = $listener->processIpn();
    } catch (Exception $e) {
        //exit(0);
    }
    /*
    The processIpn() method returned true if the IPN was "VERIFIED" and false if it
    was "INVALID".
    */
    if ($verified || isset($_POST['verification_override']) || (isset($rcp_options['sandbox']) || isset($rcp_options['disable_ipn_verify']))) {
        $posted = apply_filters('rcp_ipn_post', $_POST);
        // allow $_POST to be modified
        $user_id = $posted['custom'];
        $subscription_name = $posted['item_name'];
        $subscription_key = $posted['item_number'];
        $amount = number_format((double) $posted['mc_gross'], 2);
        $amount2 = number_format((double) $posted['mc_amount3'], 2);
        $payment_status = $posted['payment_status'];
        $currency_code = $posted['mc_currency'];
        $subscription_id = rcp_get_subscription_id($user_id);
        $subscription_price = number_format((double) rcp_get_subscription_price(rcp_get_subscription_id($user_id)), 2);
        $user_data = get_userdata($user_id);
        if (!$user_data || !$subscription_id) {
            return;
        }
        if (!rcp_get_subscription_details($subscription_id)) {
            return;
        }
        // setup the payment info in an array for storage
        $payment_data = array('date' => date('Y-m-d g:i:s', strtotime($posted['payment_date'])), 'subscription' => $posted['item_name'], 'payment_type' => $posted['txn_type'], 'subscription_key' => $subscription_key, 'amount' => $amount, 'user_id' => $user_id, 'transaction_id' => $posted['txn_id']);
        do_action('rcp_valid_ipn', $payment_data, $user_id, $posted);
        if ($posted['txn_type'] == 'web_accept' || $posted['txn_type'] == 'subscr_payment') {
            // only check for an existing payment if this is a payment IPD request
            if (rcp_check_for_existing_payment($posted['txn_type'], $posted['payment_date'], $subscription_key)) {
                $log_data = array('post_title' => __('Duplicate Payment', 'rcp'), 'post_content' => __('A duplicate payment was detected. The new payment was still recorded, so you may want to check into both payments.', 'rcp'), 'post_parent' => 0, 'log_type' => 'gateway_error');
                $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id);
                $log_entry = WP_Logging::insert_log($log_data, $log_meta);
                return;
                // this IPN request has already been processed
            }
            /* do some quick checks to make sure all necessary data validates */
            if ($amount < $subscription_price && $amount2 < $subscription_price) {
                /*
                				// the subscription price doesn't match, so lets check to see if it matches with a discount code
                				if( ! rcp_check_paypal_return_price_after_discount( $subscription_price, $amount, $amount2, $user_id ) ) {
                	$log_data = array(
                					    'post_title'    => __( 'Price Mismatch', 'rcp' ),
                					    'post_content'  =>  sprintf( __( 'The price in an IPN request did not match the subscription price. Payment data: %s', 'rcp' ), json_encode( $payment_data ) ),
                					    'post_parent'   => 0,
                					    'log_type'      => 'gateway_error'
                					);
                	$log_meta = array(
                					    'user_subscription' => $posted['item_name'],
                					    'user_id'           => $user_id
                					);
                					$log_entry = WP_Logging::insert_log( $log_data, $log_meta );
                	//return;
                				}
                */
            }
            if (strtolower($currency_code) != strtolower($rcp_options['currency'])) {
                // the currency code is invalid
                $log_data = array('post_title' => __('Invalid Currency Code', 'rcp'), 'post_content' => sprintf(__('The currency code in an IPN request did not match the site currency code. Payment data: %s', 'rcp'), json_encode($payment_data)), 'post_parent' => 0, 'log_type' => 'gateway_error');
                $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id);
                $log_entry = WP_Logging::insert_log($log_data, $log_meta);
                return;
            }
        }
        if (isset($rcp_options['email_ipn_reports'])) {
            wp_mail(get_bloginfo('admin_email'), __('IPN report', 'rcp'), $listener->getTextReport());
        }
        if (rcp_get_subscription_key($user_id) != $subscription_key) {
            // the subscription key is invalid
            $log_data = array('post_title' => __('Subscription Key Mismatch', 'rcp'), 'post_content' => sprintf(__('The subscription key in an IPN request did not match the subscription key recorded for the user. Payment data: %s', 'rcp'), json_encode($payment_data)), 'post_parent' => 0, 'log_type' => 'gateway_error');
            $log_meta = array('user_subscription' => $posted['item_name'], 'user_id' => $user_id);
            $log_entry = WP_Logging::insert_log($log_data, $log_meta);
            return;
        }
        /* now process the kind of subscription/payment */
        $rcp_payments = new RCP_Payments();
        // Subscriptions
        switch ($posted['txn_type']) {
            case "subscr_signup":
                // when a new user signs up
                // store the recurring payment ID
                update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']);
                // set the user's status to active
                rcp_set_status($user_id, 'active');
                if (!isset($rcp_options['disable_new_user_notices'])) {
                    wp_new_user_notification($user_id);
                }
                // send welcome email
                rcp_email_subscription_status($user_id, 'active');
                update_user_meta($user_id, 'rcp_recurring', 'yes');
                do_action('rcp_ipn_subscr_signup', $user_id);
                break;
            case "subscr_payment":
                // when a user makes a recurring payment
                // record this payment in the database
                $rcp_payments->insert($payment_data);
                $subscription = rcp_get_subscription_details(rcp_get_subscription_id($user_id));
                // update the user's expiration to correspond with the new payment
                $member_new_expiration = date('Y-m-d H:i:s', strtotime('+' . $subscription->duration . ' ' . $subscription->duration_unit . ' 23:59:59'));
                rcp_set_expiration_date($user_id, $member_new_expiration);
                update_user_meta($user_id, 'rcp_paypal_subscriber', $posted['payer_id']);
                // make sure the user's status is active
                rcp_set_status($user_id, 'active');
                update_user_meta($user_id, 'rcp_recurring', 'yes');
                delete_user_meta($user_id, '_rcp_expired_email_sent');
                do_action('rcp_ipn_subscr_payment', $user_id);
                break;
            case "subscr_cancel":
                // user is marked as cancelled but retains access until end of term
                rcp_set_status($user_id, 'cancelled');
                // set the use to no longer be recurring
                delete_user_meta($user_id, 'rcp_recurring');
                delete_user_meta($user_id, 'rcp_paypal_subscriber');
                // send sub cancelled email
                rcp_email_subscription_status($user_id, 'cancelled');
                do_action('rcp_ipn_subscr_cancel', $user_id);
                break;
            case "subscr_failed":
                do_action('rcp_ipn_subscr_failed');
                break;
            case "subscr_eot":
                // user's subscription has reach the end of its term
                // set the use to no longer be recurring
                delete_user_meta($user_id, 'rcp_recurring');
                if ('cancelled' !== rcp_get_status($user_id)) {
                    rcp_set_status($user_id, 'expired');
                    // send expired email
                    rcp_email_subscription_status($user_id, 'expired');
                }
                do_action('rcp_ipn_subscr_eot', $user_id);
                break;
            case "cart":
                return;
                // get out of here
            // get out of here
            case "express_checkout":
                return;
                // get out of here
            // get out of here
            case "web_accept":
                switch (strtolower($payment_status)) {
                    case 'completed':
                        if (isset($_POST['verification_override'])) {
                            // this is a method for providing a new expiration if it doesn't exist
                            $subscription = rcp_get_subscription_details_by_name($payment_data['subscription']);
                            // update the user's expiration to correspond with the new payment
                            $member_new_expiration = date('Y-m-d H:i:s', strtotime('+' . $subscription->duration . ' ' . $subscription->duration_unit . ' 23:59:59'));
                            rcp_set_expiration_date($user_id, $member_new_expiration);
                        }
                        // set this user to active
                        rcp_set_status($user_id, 'active');
                        $rcp_payments->insert($payment_data);
                        rcp_email_subscription_status($user_id, 'active');
                        if (!isset($rcp_options['disable_new_user_notices'])) {
                            // send welcome email here
                            wp_new_user_notification($user_id);
                        }
                        delete_user_meta($user_id, '_rcp_expired_email_sent');
                        break;
                    case 'denied':
                    case 'expired':
                    case 'failed':
                    case 'voided':
                        rcp_set_status($user_id, 'cancelled');
                        // send cancelled email here
                        break;
                }
                break;
            default:
                break;
        }
    } else {
        if (isset($rcp_options['email_ipn_reports'])) {
            // an invalid IPN attempt was made. Send an email to the admin account to investigate
            wp_mail(get_bloginfo('admin_email'), __('Invalid IPN', 'rcp'), $listener->getTextReport());
        }
    }
}
Пример #3
0
/**
 * Insert a payment into the database
 *
 * @deprecated  1.5
 * @access      private
 * @param       $payment_data ARRAY The data to store
 * @return      INT the ID of the new payment, or false if insertion fails
*/
function rcp_insert_payment($payment_data = array())
{
    global $wpdb, $rcp_payments_db_name;
    $amount = $payment_data['amount'];
    if ($payment_data['amount'] == '') {
        $amount = $payment_data['amount2'];
    }
    if (rcp_check_for_existing_payment($payment_data['payment_type'], $payment_data['date'], $payment_data['subscription_key'])) {
        return;
    }
    $wpdb->insert($rcp_payments_db_name, array('subscription' => $payment_data['subscription'], 'date' => $payment_data['date'], 'amount' => $amount, 'user_id' => $payment_data['user_id'], 'payment_type' => $payment_data['payment_type'], 'subscription_key' => $payment_data['subscription_key']), array('%s', '%s', '%s', '%d', '%s', '%s'));
    // if insert was succesful, return the payment ID
    if ($wpdb->insert_id) {
        // clear the payment caches
        delete_transient('rcp_payments');
        delete_transient('rcp_earnings');
        delete_transient('rcp_payments_count');
        do_action('rcp_insert_payment', $wpdb->insert_id, $payment_data, $amount);
        return $wpdb->insert_id;
    }
    // return false if payment wasn't recorded
    return false;
}
 public function process_webhooks()
 {
     if (!isset($_GET['listener']) || strtolower($_GET['listener']) != 'stripe') {
         return;
     }
     // Ensure listener URL is not cached by W3TC
     define('DONOTCACHEPAGE', true);
     \Stripe\Stripe::setApiKey($this->secret_key);
     // retrieve the request's body and parse it as JSON
     $body = @file_get_contents('php://input');
     $event_json_id = json_decode($body);
     // for extra security, retrieve from the Stripe API
     if (isset($event_json_id->id)) {
         $rcp_payments = new RCP_Payments();
         $event_id = $event_json_id->id;
         try {
             $event = \Stripe\Event::retrieve($event_id);
             $invoice = $event->data->object;
             if (empty($invoice->customer)) {
                 die('no customer attached');
             }
             // retrieve the customer who made this payment (only for subscriptions)
             $user = rcp_get_member_id_from_profile_id($invoice->customer);
             if (empty($user)) {
                 // Grab the customer ID from the old meta keys
                 global $wpdb;
                 $user = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = '_rcp_stripe_user_id' AND meta_value = %s LIMIT 1", $invoice->customer));
             }
             if (empty($user)) {
                 die('no user ID found');
             }
             $member = new RCP_Member($user);
             // check to confirm this is a stripe subscriber
             if ($member) {
                 // successful payment
                 if ($event->type == 'charge.succeeded') {
                     if (!$member->get_subscription_id()) {
                         die('no subscription ID for member');
                     }
                     $payment_data = array('date' => date('Y-m-d g:i:s', $event->created), 'subscription' => $member->get_subscription_name(), 'payment_type' => 'Credit Card', 'subscription_key' => $member->get_subscription_key(), 'amount' => $invoice->amount / 100, 'user_id' => $member->ID, 'transaction_id' => $invoice->id);
                     if (!rcp_check_for_existing_payment($payment_data['payment_type'], $payment_data['date'], $payment_data['subscription_key'])) {
                         // record this payment if it hasn't been recorded yet
                         $rcp_payments->insert($payment_data);
                         $member->renew($member->is_recurring());
                         do_action('rcp_stripe_charge_succeeded', $user, $payment_data);
                         die('rcp_stripe_charge_succeeded action fired successfully');
                     } else {
                         die('duplicate payment found');
                     }
                 }
                 // failed payment
                 if ($event->type == 'charge.failed') {
                     do_action('rcp_stripe_charge_failed', $invoice);
                     die('rcp_stripe_charge_failed action fired successfully');
                 }
                 // Cancelled / failed subscription
                 if ($event->type == 'customer.subscription.deleted') {
                     $member->set_status('cancelled');
                     die('member cancelled successfully');
                 }
                 do_action('rcp_stripe_' . $event->type, $invoice);
             }
         } catch (Exception $e) {
             // something failed
             die('PHP exception: ' . $e->getMessage());
         }
         die('1');
     }
     die('no event ID found');
 }