Example #1
0
 protected function onPaymentNotification()
 {
     if (!$this->canRun()) {
         return;
     }
     ob_end_clean();
     $name = $this->getTranslation($this->params->get('payment_name', 'PayPal'));
     require_once JPATH_ADMINISTRATOR . '/components/com_rsmembership/helpers/adapters/input.php';
     $db = JFactory::getDBO();
     $query = $db->getQuery(true);
     $jinput = RSInput::create();
     $log = array();
     $req = $this->_buildPostData();
     $this->addLog("IPN received: {$req}");
     // post back to PayPal system to validate
     $url = $this->params->get('mode') ? 'https://www.paypal.com/cgi-bin/webscr' : 'https://www.sandbox.paypal.com/cgi-bin/webscr';
     $only_completed = (int) $this->params->get('only_completed', 0);
     if (!extension_loaded('curl') || !function_exists('curl_exec') || !is_callable('curl_exec')) {
         $this->addLog('[err] cURL is not installed or executable, cannot connect back to PayPal for validation!');
         $this->finish();
     }
     $this->addLog("Connecting to {$url} to verify if PayPal response is valid.");
     require_once JPATH_ADMINISTRATOR . '/components/com_rsmembership/helpers/version.php';
     $version = (string) new RSMembershipVersion();
     $website = JUri::root();
     $ch = curl_init();
     curl_setopt($ch, CURLOPT_URL, $url);
     curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
     curl_setopt($ch, CURLOPT_POST, 1);
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
     curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
     curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
     curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: www.paypal.com'));
     curl_setopt($ch, CURLOPT_USERAGENT, "RSMembership!/{$version} ({$website})");
     $res = curl_exec($ch);
     $errstr = curl_error($ch);
     curl_close($ch);
     if ($errstr) {
         $this->addLog('[err] cURL reported error: ' . $errstr);
         $this->finish();
     }
     // assign posted variables to local variables
     $item_name = $jinput->get('item_name', '', 'none');
     $item_number = $jinput->get('item_number', '', 'none');
     $payment_status = $jinput->get('payment_status', '', 'none');
     $payment_amount = $jinput->get('mc_gross', '', 'none');
     $payment_currency = $jinput->get('mc_currency', '', 'none');
     $txn_id = $jinput->get('txn_id', '', 'none');
     $txn_type = $jinput->get('txn_type', '', 'none');
     $receiver_email = $jinput->get('receiver_email', '', 'none');
     $payer_email = $jinput->get('payer_email', '', 'none');
     $custom = $jinput->get('custom', 0, 'none');
     // try to get the transaction id based on the custom hash
     $transaction_id = $this->getTransactionId($custom);
     // Do not deny the transaction for now.
     $deny = false;
     $this->addLog("Transaction ID is '{$transaction_id}', based on '{$custom}'.");
     if ($res) {
         $this->addLog("Successfully connected to {$url}. Response is {$res}");
         if (strcmp($res, "VERIFIED") == 0) {
             $this->addLog("Response is VERIFIED.");
             $log[] = "PayPal reported a valid transaction.";
             $log[] = "Payment status is " . (!empty($payment_status) ? $payment_status : 'empty') . ".";
             // check the payment_status is Completed
             if (!$only_completed || $only_completed && $payment_status == 'Completed') {
                 // sign up - do nothing, we use our "custom" parameter to identify the transaction
                 if ($txn_type == 'subscr_signup') {
                     $log[] = "Subscription signup has been received.";
                     // If this is a free trial, we'll need to make sure that the transaction is accepted since "subscr_payment" will be received after the trial ends
                     $mc_amount1 = $jinput->get('mc_amount1', '', 'none');
                     $subscr_id = $jinput->get('subscr_id', '', 'none');
                     if ((double) $mc_amount1 == (double) $transaction->price && $mc_amount1 == '0.00') {
                         // Emulate the variables needed below to approve the transaction
                         // No txn_id here, let's just use subscr_id so we can use something for PayPal identification.
                         $txn_id = 'Subscription ID: ' . $subscr_id;
                         $payment_amount = $mc_amount1;
                         // Load the transaction so that it can be processed below
                         $transaction = $this->getTransaction($transaction_id, 'id');
                     }
                 } elseif ($txn_type == 'subscr_payment' || $txn_type == 'recurring_payment') {
                     $log[] = "Adding new payment...";
                     // check that txn_id has not been previously processed
                     // check custom_hash from db -> if custom_hash == txn_id
                     $query->clear();
                     $query->select($db->qn('id'))->from($db->qn('#__rsmembership_transactions'))->where($db->qn('hash') . ' = ' . $db->q($txn_id))->where($db->qn('gateway') . ' = ' . $db->q($name));
                     $db->setQuery($query);
                     if (!$db->loadResult()) {
                         $transaction = $this->getTransaction($custom);
                         // check if transaction exists
                         if (!empty($transaction)) {
                             // this transaction has already been processed
                             // we need to create a new "renewal" transaction
                             if ($transaction->status == 'completed') {
                                 $log[] = "Identified this payment as recurring.";
                                 $query->clear();
                                 $query->select($db->qn('id'))->select($db->qn('user_id'))->select($db->qn('membership_id'))->from($db->qn('#__rsmembership_membership_subscribers'))->where($db->qn('from_transaction_id') . ' = ' . $db->q($transaction->id));
                                 $db->setQuery($query);
                                 $membership = $db->loadObject();
                                 if (!empty($membership)) {
                                     $user = JFactory::getUser($membership->user_id);
                                     JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_rsmembership/tables');
                                     $transaction = JTable::getInstance('Transaction', 'RSMembershipTable');
                                     $transaction->user_id = $user->get('id');
                                     $transaction->user_email = $user->get('email');
                                     $transaction->type = 'renew';
                                     $params = array();
                                     $params[] = 'id=' . $membership->id;
                                     $params[] = 'membership_id=' . $membership->membership_id;
                                     $transaction->params = implode(';', $params);
                                     // params, membership, extras etc
                                     $date = JFactory::getDate();
                                     $transaction->date = $date->toSql();
                                     $transaction->ip = $_SERVER['REMOTE_ADDR'];
                                     $transaction->price = $payment_amount;
                                     $transaction->currency = RSMembershipHelper::getConfig('currency');
                                     $transaction->hash = '';
                                     $transaction->gateway = $name;
                                     $transaction->status = 'pending';
                                     // store the transaction
                                     $transaction->store();
                                     RSMembership::finalize($transaction->id);
                                     $log[] = "Successfully added the recurring transaction to the database.";
                                 } else {
                                     $log[] = "Could not identify the original transaction for this recurring payment.";
                                 }
                             }
                         } else {
                             $log[] = "Could not identify transaction with custom hash {$custom}. Stopping.";
                         }
                     } else {
                         $log[] = "The transaction {$txn_id} has already been processed. Stopping.";
                     }
                 } else {
                     // check that txn_id has not been previously processed
                     // check custom_hash from db -> if custom_hash == txn_id
                     $query->clear();
                     $query->select($db->qn('id'))->from($db->qn('#__rsmembership_transactions'))->where($db->qn('hash') . ' = ' . $db->q($txn_id))->where($db->qn('gateway') . ' = ' . $db->q($name));
                     $db->setQuery($query);
                     if (!$db->loadResult()) {
                         $query->clear();
                         $query->select('*')->from($db->qn('#__rsmembership_transactions'))->where($db->qn('custom') . ' = ' . $db->q($custom))->where($db->qn('status') . ' != ' . $db->q('completed'));
                         $db->setQuery($query);
                         $transaction = $db->loadObject();
                         // check if transaction exists
                         if (empty($transaction)) {
                             $log[] = "Could not identify transaction with custom hash {$custom}. Stopping.";
                         }
                     } else {
                         $log[] = "The transaction {$txn_id} has already been processed. Stopping.";
                     }
                 }
                 if (!empty($transaction)) {
                     $plugin_email = $this->normalize($this->params->get('email'));
                     $primary_email = $this->normalize($this->params->get('primary_email'));
                     $receiver_email = $this->normalize($receiver_email);
                     if (!$primary_email) {
                         $primary_email = $plugin_email;
                     }
                     // check that receiver_email is your Primary PayPal email
                     if ($receiver_email == $plugin_email || $receiver_email == $primary_email) {
                         // check that payment_amount/payment_currency are correct
                         // check $payment_amount == $price from $subscription_id && $payment_currency == $price from $subscription_id
                         $price = $this->_convertNumber($transaction->price);
                         $currency = $this->normalize(RSMembershipHelper::getConfig('currency'));
                         $payment_currency = $this->normalize($payment_currency);
                         if ((double) $payment_amount >= (double) $price) {
                             if ($currency == $payment_currency) {
                                 // set the hash
                                 $this->setTransactionHash($transaction->id, $txn_id);
                                 // process payment unless manual activation selected
                                 $membership_id = $this->getMembershipId($transaction->params, $transaction->type);
                                 if ($membership_id) {
                                     $query->clear()->select('activation')->from($db->qn('#__rsmembership_memberships'))->where($db->qn('id') . ' = ' . $db->q((int) $membership_id));
                                     $db->setQuery($query);
                                     $activation = $db->loadResult();
                                     if ($activation != MEMBERSHIP_ACTIVATION_MANUAL) {
                                         RSMembership::approve($transaction->id);
                                     }
                                     $activationText = 'missing';
                                     if ($activation == MEMBERSHIP_ACTIVATION_MANUAL) {
                                         $activationText = 'manual';
                                     } elseif ($activation == MEMBERSHIP_ACTIVATION_AUTO) {
                                         $activationText = 'auto';
                                     } elseif ($activation == MEMBERSHIP_ACTIVATION_INSTANT) {
                                         $activationText = 'instant';
                                     }
                                     $log[] = "Activation is {$activationText}.";
                                     $log[] = "Successfully added the payment to the database.";
                                 } else {
                                     $log[] = "The membership could not be found in the database.";
                                 }
                             } else {
                                 $log[] = "Expected a currency of {$currency}. PayPal reports this payment is made in {$payment_currency}. Stopping.";
                                 $deny = true;
                             }
                         } else {
                             $log[] = "Expected an amount of {$price} {$currency}. PayPal reports this payment is {$payment_amount} {$payment_currency}. Stopping.";
                             $deny = true;
                         }
                     } else {
                         $log[] = "Expected payment to be made to {$plugin_email}" . ($primary_email ? " or {$primary_email}" : "") . ". PayPal reports this payment is made for {$receiver_email}. Stopping.";
                         $deny = true;
                     }
                 }
             } else {
                 $log[] = "Payment status is {$payment_status}. Stopping.";
             }
         } elseif (strcmp($res, "INVALID") == 0) {
             $this->addLog("[err] Response is INVALID.");
             $log[] = "Could not verify transaction authencity. PayPal said it's invalid.";
             $log[] = "String sent to PayPal is {$req}";
             $deny = true;
             // log for manual investigation
         } else {
             $this->addLog("[err] PayPal response returned invalid data. Data is presented below:");
             $this->addLog($res);
             $this->addLog("End of data.");
             $log[] = 'PayPal response is not valid! Should be either VERIFIED or INVALID, received "' . strip_tags($res) . '"';
         }
     } else {
         $log[] = "Could not open {$url} in order to verify this transaction. Error reported is: {$errstr}";
     }
     if ($transaction_id) {
         $log[] = "String sent by PayPal is {$req}";
         RSMembership::saveTransactionLog($log, $transaction_id);
         if ($deny) {
             RSMembership::deny($transaction_id);
         }
     }
     $this->finish();
 }
Example #2
0
 public function deny()
 {
     // Check for request forgeries
     JSession::checkToken() or jexit('Invalid Token');
     // Get the selected items
     $cid = JFactory::getApplication()->input->get('cid', array(), 'array');
     // Force array elements to be integers
     JArrayHelper::toInteger($cid, array(0));
     $msg = '';
     // No items are selected
     if (!is_array($cid) || count($cid) < 1) {
         JError::raiseWarning(500, JText::_('JERROR_NO_ITEMS_SELECTED'));
     } else {
         $user = JFactory::getUser();
         $user_id = $user->get('username');
         $total = 0;
         foreach ($cid as $id) {
             RSMembership::saveTransactionLog('Manually denied by ' . $user_id, $id);
             if (RSMembership::deny($id)) {
                 $total++;
             }
         }
         $msg = JText::sprintf('COM_RSMEMBERSHIP_TRANSACTIONS_DENIED', $total);
         // Clean the cache, if any
         $cache = JFactory::getCache('com_rsmembership');
         $cache->clean();
     }
     $this->setRedirect(JRoute::_('index.php?option=com_rsmembership&view=transactions', false), $msg);
 }
Example #3
0
 function deny()
 {
     // Check for request forgeries
     JRequest::checkToken() or jexit('Invalid Token');
     // Get the selected items
     $cid = JRequest::getVar('cid', array(0), 'post', 'array');
     $total = count($cid);
     $msg = JText::sprintf('RSM_TRANSACTIONS_DENIED', $total);
     // Force array elements to be integers
     JArrayHelper::toInteger($cid, array(0));
     $msg = '';
     // No items are selected
     if (!is_array($cid) || count($cid) < 1) {
         JError::raiseWarning(500, JText::_('SELECT ITEM'));
     } else {
         $user =& JFactory::getUser();
         $user_id = $user->get('username');
         foreach ($cid as $id) {
             RSMembership::saveTransactionLog('Manually denied by ' . $user_id, $id);
             RSMembership::deny($id);
         }
         $total = count($cid);
         $msg = JText::sprintf('RSM_TRANSACTIONS_DENIED', $total);
         // Clean the cache, if any
         $cache =& JFactory::getCache('com_rsmembership');
         $cache->clean();
     }
     $this->setRedirect('index.php?option=com_rsmembership&view=transactions', $msg);
 }
Example #4
0
 protected function onOldPaymentNotification()
 {
     if (!$this->canRun()) {
         return;
     }
     $log = array();
     $deny = false;
     $app = JFactory::getApplication();
     $jinput = $app->input;
     $db = JFactory::getDBO();
     $query = $db->getQuery(true);
     $recurring = $jinput->get('recurring', 0, 'int');
     $custom = $jinput->get('custom', '', 'string');
     $ordernumber = $this->params->get('mode') ? $jinput->get('order_number', '', 'string') : 1;
     $total = $jinput->get('total', '', 'string');
     $key = $jinput->get('key', '', 'string');
     $processed = $jinput->get('credit_card_processed', '', 'string');
     $timestamp = $jinput->get('timestamp', '', 'string');
     $payment_amount = $jinput->get('payment_amount', '', 'string');
     $query->select('*')->from($db->qn('#__rsmembership_transactions'))->where($db->qn('custom') . ' = ' . $db->q($custom));
     $db->setQuery($query);
     $db->execute();
     $transaction = $db->loadObject();
     $secret_word = $this->params->get('secret_word');
     $sid = $this->params->get('id');
     // calculate the hash
     $hash = strtoupper(md5($secret_word . $sid . $ordernumber . $total));
     if ($hash != $key) {
         $log[] = JText::sprintf("PLG_SYSTEM_RSMEMBERSHIP2CO_VERIFICATION_ERROR", $key, $hash);
         $deny = true;
     } else {
         if ($recurring) {
             // recurring payment
             $log[] = "Identified this payment as recurring.";
             $query->clear();
             $query->select($db->qn('id'))->select($db->qn('user_id'))->select($db->qn('membership_id'))->from($db->qn('#__rsmembership_membership_subscribers'))->where($db->qn('from_transaction_id') . ' = ' . $db->q($transaction->id));
             $db->setQuery($query);
             $membership = $db->loadObject();
             if (!empty($membership)) {
                 $user = JFactory::getUser($membership->user_id);
                 // get the serialized user_data from previous transaction
                 $user_data = $transaction->user_data;
                 // load new transaction object
                 JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_rsmembership/tables');
                 $transaction = JTable::getInstance('Transaction', 'RSMembershipTable');
                 $transaction->user_id = $user->get('id');
                 $transaction->user_email = $user->get('email');
                 $transaction->user_data = $user_data;
                 $transaction->type = 'renew';
                 $params = array();
                 $params[] = 'id=' . $membership->id;
                 $params[] = 'membership_id=' . $membership->membership_id;
                 $transaction->params = implode(';', $params);
                 // params, membership, extras etc
                 $transaction->ip = $_SERVER['REMOTE_ADDR'];
                 $transaction->date = $timestamp;
                 $transaction->price = $payment_amount;
                 $transaction->currency = RSMembershipHelper::getConfig('currency');
                 $transaction->hash = '';
                 $transaction->gateway = $this->getTranslation($this->params->get('payment_name', '2Checkout'));
                 $transaction->status = 'completed';
                 // store the transaction
                 $transaction->store();
                 RSMembership::finalize($transaction->id);
                 $log[] = "Successfully added the recurring transaction to the database.";
             } else {
                 $log[] = "Could not identify the original transaction for this recurring payment.";
             }
         } else {
             // transaction exists
             if (empty($transaction) || $transaction->status == 'completed') {
                 return;
             }
             // check if the amount is correct
             $price = $this->_convertNumber($transaction->price);
             $currency = strtolower(trim(RSMembershipHelper::getConfig('currency')));
             if ($price <= $total) {
                 // process payment
                 if ($processed == 'Y') {
                     // update order number
                     $query->clear();
                     $query->update($db->qn('#__rsmembership_transactions'))->set($db->qn('hash') . ' = ' . $db->q($ordernumber))->where($db->qn('id') . ' = ' . $db->q($transaction->id));
                     $db->setQuery($query);
                     $db->execute();
                     // approve
                     RSMembership::approve($transaction->id);
                     $log[] = JText::sprintf('PLG_SYSTEM_RSMEMBERSHIP2CO_PAYMENT_SUCCESS', $ordernumber);
                 } else {
                     $log[] = JText::_("PLG_SYSTEM_RSMEMBERSHIP2CO_CC_NOT_PROCESSED");
                     $deny = true;
                 }
             } else {
                 $log[] = JText::sprintf("PLG_SYSTEM_RSMEMBERSHIP2CO_EXPECTED_AMOUNT", $price, $currency, $total, $currency);
                 $deny = true;
             }
         }
     }
     RSMembership::saveTransactionLog($log, $transaction->id);
     if ($deny) {
         RSMembership::deny($transaction->id);
     }
     $app->redirect('index.php?option=com_rsmembership&task=thankyou');
 }