_addItem([ 'user' => $this->getUser(), 'canRenew' => $this->canRenew(), 'expired' => $this->isExpired(), 'renewExpirationDate' => $this->getRenewExpirationDate(), 'renewSince' => $this->getRenewSinceDate(), 'paymentUrl' => $this->url(['action' => 'payment']), 'tpl' => $this->getTemplate('index.tpl'), ]); return $this; } public function canRenew() { return $this->getRenewSinceDate() < date('Y-m-d'); } public function isExpired() { return $this->getUser('membershipExpiresOn') < date('Y-m-d'); } public function getRenewExpirationDate() { $startDate = $this->isExpired() ? date('Y-m-d') : $this->getUser('membershipExpiresOn'); if (!($duration = $this->getUser('membership[duration]'))) { throw new Exception('Membership duration is undefined'); } return date('Y-m-d', strtotime($startDate . " +{$duration} year")); } public function getRenewSinceDate() { $renewSince = $this->getConfig('renewSince'); return date('Y-m-d', strtotime($this->getUser('membershipExpiresOn') . " -{$renewSince} month")); } public function getUser($field = null) { static $user = []; if ([] === $user) { $user = $this->_doc->getAuthData(); $user['membership'] = (new Qs_Db_Table('MembershipType'))->search($user['membershipTypeId']); } return Qs_Array::get($user, $field); } public function _doPayment() { try { $service = PayPalServiceFactory::create(); $user = $this->getUser(); $total = [ 'currencyID' => 'USD', 'value' => $user['membership']['price'], ]; $response = $service->setExpressCheckout([ 'SetExpressCheckoutRequestDetails' => [ 'PaymentDetails' => [ 'PaymentDetailsItem' => [ 'Name' => 'Membership Renew', 'Description' => 'Member: ' . $user['firstName'] . ' ' . $user['lastName'] . '. Membership: ' . $this->getUser('membership[title]') . '. Expires on: ' . date('m/d/Y', strtotime($this->getRenewExpirationDate())), 'Quantity' => 1, 'Amount' => $total, ], 'OrderTotal' => $total, 'PaymentAction' => 'Sale', 'ItemTotal' => $total, ], 'NoShipping' => 1, 'ReqConfirmShipping' => 0, 'SolutionType' => 'Sole', 'CancelURL' => $this->url(['action' => 'cancelPayment']), 'ReturnURL' => $this->url(['action' => 'expressCheckout']), ], ]); $url = Qs_String::fill($service->getExpressCheckoutUrl(), ['token' => $response->Token]); $this->redirect($url); } catch (PayPalException $e) { $this->_setBackUrl($this->url()); $this->_setBackError($e->getMessage()); $this->_doBack(); } } protected function _doCancelPayment() { $this->redirect($this->url()); } protected function _doExpressCheckout() { $token = Qs_Request::getGetValue('token'); $payerId = Qs_Request::getGetValue('PayerID'); $service = PayPalServiceFactory::create(); $this->_setBackUrl($this->url()); try { $detailsResponse = $service->getExpressCheckoutDetails($token); $paymentDetails = current((array) $detailsResponse->GetExpressCheckoutDetailsResponseDetails->PaymentDetails); $total = [ 'currencyID' => $paymentDetails->OrderTotal->currencyID, 'value' => $paymentDetails->OrderTotal->value, ]; $response = $service->doExpressCheckoutPayment([ 'DoExpressCheckoutPaymentRequestDetails' => [ 'PayerID' => $payerId, 'Token' => $token, 'PaymentDetails' => [ 'OrderTotal' => $total, 'ItemTotal' => $total, 'PaymentAction' => 'Sale', ], ], ]); /** @var PaymentInfoType $paymentInfo */ $paymentInfo = current((array) $response->DoExpressCheckoutPaymentResponseDetails->PaymentInfo); $transactionId = $paymentInfo->TransactionID; $userId = $this->_doc->getAuthData('id'); $this->getModel()->update([ 'transactionId' => $transactionId, 'membershipExpiresOn' => $this->getRenewExpirationDate(), ], ['id' => $userId]); $user = $this->getModel()->find(['id' => $userId]); $this->notify($user); $this->_setBackMessage('Membership has been successfully renewed'); } catch (PayPalException $e) { $this->_setBackError($e->getMessage()); } $this->_doBack(); return $this; } private function notify(array $user) { Mail::sendMembershipRenewedToUser($user); return $this; } }