OJSPaymentManager::fulfillQueuedPayment PHP Method

fulfillQueuedPayment() public method

Fulfill a queued payment.
public fulfillQueuedPayment ( $request, &$queuedPayment, $payMethodPluginName = null ) : mixed
$request PKPRequest
$queuedPayment QueuedPayment
$payMethodPluginName string Name of payment plugin.
return mixed Dependent on payment type.
    function fulfillQueuedPayment($request, &$queuedPayment, $payMethodPluginName = null)
    {
        $returner = false;
        if ($queuedPayment) {
            switch ($queuedPayment->getType()) {
                case PAYMENT_TYPE_MEMBERSHIP:
                    $userDao = DAORegistry::getDAO('UserDAO');
                    $user =& $userDao->getById($queuedPayment->getuserId());
                    $userDao->renewMembership($user);
                    $returner = true;
                    break;
                case PAYMENT_TYPE_PURCHASE_SUBSCRIPTION:
                    $subscriptionId = $queuedPayment->getAssocId();
                    $institutionalSubscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO');
                    $individualSubscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO');
                    if ($institutionalSubscriptionDao->subscriptionExists($subscriptionId)) {
                        $subscription =& $institutionalSubscriptionDao->getSubscription($subscriptionId);
                        $institutional = true;
                    } else {
                        $subscription =& $individualSubscriptionDao->getSubscription($subscriptionId);
                        $institutional = false;
                    }
                    if (!$subscription || $subscription->getUserId() != $queuedPayment->getUserId() || $subscription->getJournalId() != $queuedPayment->getJournalId()) {
                        // FIXME: Is this supposed to be here?
                        error_log(print_r($subscription, true));
                        return false;
                    }
                    // Update subscription end date now that payment is completed
                    if ($institutional) {
                        // Still requires approval from JM/SM since includes domain and IP ranges
                        import('classes.subscription.InstitutionalSubscription');
                        $subscription->setStatus(SUBSCRIPTION_STATUS_NEEDS_APPROVAL);
                        if ($subscription->isNonExpiring()) {
                            $institutionalSubscriptionDao->updateSubscription($subscription);
                        } else {
                            $institutionalSubscriptionDao->renewSubscription($subscription);
                        }
                        // Notify JM/SM of completed online purchase
                        $journalSettingsDao = DAORegistry::getDAO('JournalSettingsDAO');
                        if ($journalSettingsDao->getSetting($subscription->getJournalId(), 'enableSubscriptionOnlinePaymentNotificationPurchaseInstitutional')) {
                            import('classes.subscription.SubscriptionAction');
                            SubscriptionAction::sendOnlinePaymentNotificationEmail($request, $subscription, 'SUBSCRIPTION_PURCHASE_INSTL');
                        }
                    } else {
                        import('classes.subscription.IndividualSubscription');
                        $subscription->setStatus(SUBSCRIPTION_STATUS_ACTIVE);
                        if ($subscription->isNonExpiring()) {
                            $individualSubscriptionDao->updateSubscription($subscription);
                        } else {
                            $individualSubscriptionDao->renewSubscription($subscription);
                        }
                        // Notify JM/SM of completed online purchase
                        $journalSettingsDao = DAORegistry::getDAO('JournalSettingsDAO');
                        if ($journalSettingsDao->getSetting($subscription->getJournalId(), 'enableSubscriptionOnlinePaymentNotificationPurchaseIndividual')) {
                            import('classes.subscription.SubscriptionAction');
                            SubscriptionAction::sendOnlinePaymentNotificationEmail($request, $subscription, 'SUBSCRIPTION_PURCHASE_INDL');
                        }
                    }
                    $returner = true;
                    break;
                case PAYMENT_TYPE_RENEW_SUBSCRIPTION:
                    $subscriptionId = $queuedPayment->getAssocId();
                    $institutionalSubscriptionDao = DAORegistry::getDAO('InstitutionalSubscriptionDAO');
                    $individualSubscriptionDao = DAORegistry::getDAO('IndividualSubscriptionDAO');
                    if ($institutionalSubscriptionDao->subscriptionExists($subscriptionId)) {
                        $subscription =& $institutionalSubscriptionDao->getSubscription($subscriptionId);
                        $institutional = true;
                    } else {
                        $subscription =& $individualSubscriptionDao->getSubscription($subscriptionId);
                        $institutional = false;
                    }
                    if (!$subscription || $subscription->getUserId() != $queuedPayment->getUserId() || $subscription->getJournalId() != $queuedPayment->getJournalId()) {
                        // FIXME: Is this supposed to be here?
                        error_log(print_r($subscription, true));
                        return false;
                    }
                    if ($institutional) {
                        $institutionalSubscriptionDao->renewSubscription($subscription);
                        // Notify JM/SM of completed online purchase
                        $journalSettingsDao = DAORegistry::getDAO('JournalSettingsDAO');
                        if ($journalSettingsDao->getSetting($subscription->getJournalId(), 'enableSubscriptionOnlinePaymentNotificationRenewInstitutional')) {
                            import('classes.subscription.SubscriptionAction');
                            SubscriptionAction::sendOnlinePaymentNotificationEmail($request, $subscription, 'SUBSCRIPTION_RENEW_INSTL');
                        }
                    } else {
                        $individualSubscriptionDao->renewSubscription($subscription);
                        // Notify JM/SM of completed online purchase
                        $journalSettingsDao = DAORegistry::getDAO('JournalSettingsDAO');
                        if ($journalSettingsDao->getSetting($subscription->getJournalId(), 'enableSubscriptionOnlinePaymentNotificationRenewIndividual')) {
                            import('classes.subscription.SubscriptionAction');
                            SubscriptionAction::sendOnlinePaymentNotificationEmail($request, $subscription, 'SUBSCRIPTION_RENEW_INDL');
                        }
                    }
                    $returner = true;
                    break;
                case PAYMENT_TYPE_FASTTRACK:
                    $articleDao = DAORegistry::getDAO('ArticleDAO');
                    $article = $articleDao->getById($queuedPayment->getAssocId(), $queuedPayment->getJournalId());
                    $article->setFastTracked(true);
                    $articleDao->updateObject($article);
                    $returner = true;
                    break;
                case PAYMENT_TYPE_GIFT:
                    $giftId = $queuedPayment->getAssocId();
                    $giftDao = DAORegistry::getDAO('GiftDAO');
                    $gift =& $giftDao->getGift($giftId);
                    if (!$gift) {
                        return false;
                    }
                    $password = null;
                    // Suppress scrutinizer warn
                    $journalDao = DAORegistry::getDAO('JournalDAO');
                    $journalId = $gift->getAssocId();
                    $journal = $journalDao->getById($journalId);
                    if (!$journal) {
                        return false;
                    }
                    // Check if user account corresponding to recipient email exists in the system
                    $userDao = DAORegistry::getDAO('UserDAO');
                    $roleDao = DAORegistry::getDAO('RoleDAO');
                    $recipientFirstName = $gift->getRecipientFirstName();
                    $recipientEmail = $gift->getRecipientEmail();
                    $newUserAccount = false;
                    if ($userDao->userExistsByEmail($recipientEmail)) {
                        // User already has account, check if enrolled as reader in journal
                        $user = $userDao->getUserByEmail($recipientEmail);
                        $userId = $user->getId();
                        if (!$roleDao->userHasRole($journalId, $userId, ROLE_ID_READER)) {
                            // User not enrolled as reader, enroll as reader
                            $role = new Role();
                            $role->setJournalId($journalId);
                            $role->setUserId($userId);
                            $role->setRoleId(ROLE_ID_READER);
                            $roleDao->insertRole($role);
                        }
                    } else {
                        // User does not have an account. Create one and enroll as reader.
                        $recipientLastName = $gift->getRecipientLastName();
                        $username = Validation::suggestUsername($recipientFirstName, $recipientLastName);
                        $password = Validation::generatePassword();
                        $user = $userDao->newDataObject();
                        $user->setUsername($username);
                        $user->setPassword(Validation::encryptCredentials($username, $password));
                        $user->setFirstName($recipientFirstName);
                        $user->setMiddleName($gift->getRecipientMiddleName());
                        $user->setLastName($recipientLastName);
                        $user->setEmail($recipientEmail);
                        $user->setDateRegistered(Core::getCurrentDate());
                        $userDao->insertObject($user);
                        $userId = $user->getId();
                        $role = new Role();
                        $role->setJournalId($journalId);
                        $role->setUserId($userId);
                        $role->setRoleId(ROLE_ID_READER);
                        $roleDao->insertRole($role);
                        $newUserAccount = true;
                    }
                    // Update gift status (make it redeemable) and add recipient user account reference
                    import('classes.gift.Gift');
                    $gift->setStatus(GIFT_STATUS_NOT_REDEEMED);
                    $gift->setRecipientUserId($userId);
                    $giftDao->updateObject($gift);
                    // Send gift available email to recipient, cc buyer
                    $giftNoteTitle = $gift->getGiftNoteTitle();
                    $buyerFullName = $gift->getBuyerFullName();
                    $giftNote = $gift->getGiftNote();
                    $giftLocale = $gift->getLocale();
                    AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, $giftLocale);
                    $giftDetails = $gift->getGiftName($giftLocale);
                    $giftJournalName = $journal->getName($giftLocale);
                    $giftContactSignature = $journal->getSetting('contactName');
                    import('lib.pkp.classes.mail.MailTemplate');
                    $mail = new MailTemplate('GIFT_AVAILABLE', $giftLocale);
                    $mail->setReplyTo(null);
                    $mail->assignParams(array('giftJournalName' => $giftJournalName, 'giftNoteTitle' => $giftNoteTitle, 'recipientFirstName' => $recipientFirstName, 'buyerFullName' => $buyerFullName, 'giftDetails' => $giftDetails, 'giftNote' => $giftNote, 'giftContactSignature' => $giftContactSignature));
                    $mail->addRecipient($recipientEmail, $user->getFullName());
                    $mail->addCc($gift->getBuyerEmail(), $gift->getBuyerFullName());
                    $mail->send();
                    unset($mail);
                    // Send gift login details to recipient
                    $params = array('giftJournalName' => $giftJournalName, 'recipientFirstName' => $recipientFirstName, 'buyerFullName' => $buyerFullName, 'giftDetails' => $giftDetails, 'giftUrl' => $request->url($journal->getPath(), 'user', 'gifts'), 'username' => $user->getUsername(), 'giftContactSignature' => $giftContactSignature);
                    if ($newUserAccount) {
                        $mail = new MailTemplate('GIFT_USER_REGISTER', $giftLocale);
                        $params['password'] = $password;
                    } else {
                        $mail = new MailTemplate('GIFT_USER_LOGIN', $giftLocale);
                    }
                    $mail->setReplyTo(null);
                    $mail->assignParams($params);
                    $mail->addRecipient($recipientEmail, $user->getFullName());
                    $mail->send();
                    unset($mail);
                    $returner = true;
                    break;
                case PAYMENT_TYPE_PURCHASE_ARTICLE:
                case PAYMENT_TYPE_PURCHASE_ISSUE:
                case PAYMENT_TYPE_DONATION:
                case PAYMENT_TYPE_SUBMISSION:
                case PAYMENT_TYPE_PUBLICATION:
                    $returner = true;
                    break;
                default:
                    // Invalid payment type
                    assert(false);
            }
        }
        $completedPaymentDao = DAORegistry::getDAO('OJSCompletedPaymentDAO');
        $completedPayment =& $this->createCompletedPayment($queuedPayment, $payMethodPluginName);
        $completedPaymentDao->insertCompletedPayment($completedPayment);
        $queuedPaymentDao = DAORegistry::getDAO('QueuedPaymentDAO');
        $queuedPaymentDao->deleteQueuedPayment($queuedPayment->getId());
        return $returner;
    }

Usage Example

Example #1
0
 /**
  * Handle incoming requests/notifications
  * @param $args array
  * @param $request PKPRequest
  */
 function handle($args, $request)
 {
     $templateMgr = TemplateManager::getManager($request);
     $journal = $request->getJournal();
     if (!$journal) {
         return parent::handle($args, $request);
     }
     // Just in case we need to contact someone
     import('lib.pkp.classes.mail.MailTemplate');
     // Prefer technical support contact
     $contactName = $journal->getSetting('supportName');
     $contactEmail = $journal->getSetting('supportEmail');
     if (!$contactEmail) {
         // Fall back on primary contact
         $contactName = $journal->getSetting('contactName');
         $contactEmail = $journal->getSetting('contactEmail');
     }
     $mail = new MailTemplate('PAYPAL_INVESTIGATE_PAYMENT');
     $mail->setReplyTo(null);
     $mail->addRecipient($contactEmail, $contactName);
     $paymentStatus = $request->getUserVar('payment_status');
     switch (array_shift($args)) {
         case 'ipn':
             // Build a confirmation transaction.
             $req = 'cmd=_notify-validate';
             if (get_magic_quotes_gpc()) {
                 foreach ($_POST as $key => $value) {
                     $req .= '&' . urlencode(stripslashes($key)) . '=' . urlencode(stripslashes($value));
                 }
             } else {
                 foreach ($_POST as $key => $value) {
                     $req .= '&' . urlencode($key) . '=' . urlencode($value);
                 }
             }
             // Create POST response
             $ch = curl_init();
             curl_setopt($ch, CURLOPT_URL, $this->getSetting($journal->getId(), 'paypalurl'));
             curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
             curl_setopt($ch, CURLOPT_POST, 1);
             curl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: PKP PayPal Service', 'Content-Type: application/x-www-form-urlencoded', 'Content-Length: ' . strlen($req)));
             curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
             $ret = curl_exec($ch);
             $curlError = curl_error($ch);
             curl_close($ch);
             // Check the confirmation response and handle as necessary.
             if (strcmp($ret, 'VERIFIED') == 0) {
                 switch ($paymentStatus) {
                     case 'Completed':
                         $payPalDao = DAORegistry::getDAO('PayPalDAO');
                         $transactionId = $request->getUserVar('txn_id');
                         if ($payPalDao->transactionExists($transactionId)) {
                             // A duplicate transaction was received; notify someone.
                             $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Duplicate transaction ID: {$transactionId}", 'serverVars' => print_r($_SERVER, true)));
                             $mail->send();
                             exit;
                         } else {
                             // New transaction succeeded. Record it.
                             $payPalDao->insertTransaction($transactionId, $request->getUserVar('txn_type'), String::strtolower($request->getUserVar('payer_email')), String::strtolower($request->getUserVar('receiver_email')), $request->getUserVar('item_number'), $request->getUserVar('payment_date'), $request->getUserVar('payer_id'), $request->getUserVar('receiver_id'));
                             $queuedPaymentId = $request->getUserVar('custom');
                             import('classes.payment.ojs.OJSPaymentManager');
                             $ojsPaymentManager = new OJSPaymentManager($request);
                             // Verify the cost and user details as per PayPal spec.
                             $queuedPayment =& $ojsPaymentManager->getQueuedPayment($queuedPaymentId);
                             if (!$queuedPayment) {
                                 // The queued payment entry is missing. Complain.
                                 $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Missing queued payment ID: {$queuedPaymentId}", 'serverVars' => print_r($_SERVER, true)));
                                 $mail->send();
                                 exit;
                             }
                             //NB: if/when paypal subscriptions are enabled, these checks will have to be adjusted
                             // because subscription prices may change over time
                             $queuedAmount = $queuedPayment->getAmount();
                             $grantedAmount = $request->getUserVar('mc_gross');
                             $queuedCurrency = $queuedPayment->getCurrencyCode();
                             $grantedCurrency = $request->getUserVar('mc_currency');
                             $grantedEmail = String::strtolower($request->getUserVar('receiver_email'));
                             $queuedEmail = String::strtolower($this->getSetting($journal->getId(), 'selleraccount'));
                             if ($queuedAmount != $grantedAmount && $queuedAmount > 0 || $queuedCurrency != $grantedCurrency || $grantedEmail != $queuedEmail) {
                                 // The integrity checks for the transaction failed. Complain.
                                 $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Granted amount: {$grantedAmount}\n" . "Queued amount: {$queuedAmount}\n" . "Granted currency: {$grantedCurrency}\n" . "Queued currency: {$queuedCurrency}\n" . "Granted to PayPal account: {$grantedEmail}\n" . "Configured PayPal account: {$queuedEmail}", 'serverVars' => print_r($_SERVER, true)));
                                 $mail->send();
                                 exit;
                             }
                             // Update queued amount if amount set by user (e.g. donation)
                             if ($queuedAmount == 0 && $grantedAmount > 0) {
                                 $queuedPaymentDao = DAORegistry::getDAO('QueuedPaymentDAO');
                                 $queuedPayment->setAmount($grantedAmount);
                                 $queuedPayment->setCurrencyCode($grantedCurrency);
                                 $queuedPaymentDao->updateQueuedPayment($queuedPaymentId, $queuedPayment);
                             }
                             // Fulfill the queued payment.
                             if ($ojsPaymentManager->fulfillQueuedPayment($request, $queuedPayment, $this->getName())) {
                                 exit;
                             }
                             // If we're still here, it means the payment couldn't be fulfilled.
                             $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Queued payment ID {$queuedPaymentId} could not be fulfilled.", 'serverVars' => print_r($_SERVER, true)));
                             $mail->send();
                         }
                         exit;
                     case 'Pending':
                         // Ignore.
                         exit;
                     default:
                         // An unhandled payment status was received; notify someone.
                         $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Payment status: {$paymentStatus}", 'serverVars' => print_r($_SERVER, true)));
                         $mail->send();
                         exit;
                 }
             } else {
                 // An unknown confirmation response was received; notify someone.
                 $mail->assignParams(array('journalName' => $journal->getLocalizedName(), 'postInfo' => print_r($_POST, true), 'additionalInfo' => "Confirmation return: {$ret}\nCURL error: {$curlError}", 'serverVars' => print_r($_SERVER, true)));
                 $mail->send();
                 exit;
             }
         case 'cancel':
             Handler::setupTemplate();
             $templateMgr->assign(array('currentUrl' => $request->url(null, 'index'), 'pageTitle' => 'plugins.paymethod.paypal.purchase.cancelled.title', 'message' => 'plugins.paymethod.paypal.purchase.cancelled', 'backLink' => $request->getUserVar('ojsReturnUrl'), 'backLinkLabel' => 'common.continue'));
             $templateMgr->display('frontend/pages/message.tpl');
             exit;
     }
     parent::handle($args, $request);
     // Don't know what to do with it
 }
All Usage Examples Of OJSPaymentManager::fulfillQueuedPayment