/**
 * Determines if a member can cancel their subscription on site
 *
 * @access      public
 * @since       2.1
 */
function rcp_can_member_cancel($user_id = 0)
{
    if (empty($user_id)) {
        $user_id = get_current_user_id();
    }
    $ret = false;
    $member = new RCP_Member($user_id);
    if ($member->is_recurring() && $member->is_active() && 'cancelled' !== $member->get_status()) {
        $profile_id = $member->get_payment_profile_id();
        // Check if the member is a Stripe customer
        if (rcp_is_stripe_subscriber($user_id)) {
            $ret = true;
        } elseif (rcp_is_paypal_subscriber($user_id) && rcp_has_paypal_api_access()) {
            $ret = true;
        } elseif (rcp_is_2checkout_subscriber($user_id) && defined('TWOCHECKOUT_ADMIN_USER') && defined('TWOCHECKOUT_ADMIN_PASSWORD')) {
            $ret = true;
        }
    }
    return apply_filters('rcp_member_can_cancel', $ret, $user_id);
}
 /**
  * Proccess webhooks
  *
  * @since 2.3
  */
 public function process_webhooks()
 {
     if (isset($_GET['listener']) && $_GET['listener'] == '2checkout') {
         global $wpdb;
         $hash = strtoupper(md5($_POST['sale_id'] . $this->seller_id . $_POST['invoice_id'] . $this->secret_word));
         if (!hash_equals($hash, $_POST['md5_hash'])) {
             die('-1');
         }
         if (empty($_POST['message_type'])) {
             die('-2');
         }
         if (empty($_POST['vendor_id'])) {
             die('-3');
         }
         $subscription_key = sanitize_text_field($_POST['vendor_order_id']);
         $member_id = $wpdb->get_var($wpdb->prepare("SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key = 'rcp_subscription_key' AND meta_value = %s LIMIT 1", $subscription_key));
         if (!$member_id) {
             die('-4');
         }
         $member = new RCP_Member($member_id);
         if (!rcp_is_2checkout_subscriber($member->ID)) {
             return;
         }
         $payments = new RCP_Payments();
         switch (strtoupper($_POST['message_type'])) {
             case 'ORDER_CREATED':
                 break;
             case 'REFUND_ISSUED':
                 $payment = $payments->get_payment_by('transaction_id', $_POST['invoice_id']);
                 $payments->update($payment->id, array('status' => 'refunded'));
                 if (!empty($_POST['recurring'])) {
                     $member->cancel();
                     $member->add_note(__('Subscription cancelled via refund 2Checkout', 'rcp'));
                 }
                 break;
             case 'RECURRING_INSTALLMENT_SUCCESS':
                 $payment_data = array('date' => date('Y-m-d H:i:s', strtotime($_POST['timestamp'], current_time('timestamp'))), 'subscription' => $member->get_subscription_name(), 'payment_type' => sanitize_text_field($_POST['payment_type']), 'subscription_key' => $subscription_key, 'amount' => sanitize_text_field($_POST['item_list_amount_1']), 'user_id' => $member->ID, 'transaction_id' => sanitize_text_field($_POST['invoice_id']));
                 $recurring = !empty($_POST['recurring']);
                 $member->renew($recurring);
                 $payments->insert($payment_data);
                 $member->add_note(__('Subscription renewed in 2Checkout', 'rcp'));
                 break;
             case 'RECURRING_INSTALLMENT_FAILED':
                 break;
             case 'RECURRING_STOPPED':
                 if (!$member->just_upgraded()) {
                     $member->cancel();
                     $member->add_note(__('Subscription cancelled in 2Checkout', 'rcp'));
                 }
                 break;
             case 'RECURRING_COMPLETE':
                 break;
             case 'RECURRING_RESTARTED':
                 $member->set_status('active');
                 $member->add_note(__('Subscription restarted in 2Checkout', 'rcp'));
                 break;
             case 'FRAUD_STATUS_CHANGED':
                 switch ($_POST['fraud_status']) {
                     case 'pass':
                         break;
                     case 'fail':
                         $member->set_status('pending');
                         $member->add_note(__('Payment flagged as fraudulent in 2Checkout', 'rcp'));
                         break;
                     case 'wait':
                         break;
                 }
                 break;
         }
         do_action('rcp_2co_' . strtolower($_POST['message_type']) . '_ins', $member);
         die('success');
     }
 }