/**
  * // check whether the payment_status is Completed
  * // check that txn_id has not been previously processed
  * // check that receiver_email is your PayPal email
  * // check that payment_amount/payment_currency are correct
  * // process payment and mark item as paid.
  * // assign posted variables to local variables
  *
  * @param $myPost
  */
 public function processPayment($myPost)
 {
     $customData = $this->getCustomData($myPost);
     $userId = $customData['user_id'];
     $userService = new UserService();
     $userInfo = $userService->getUserData($userId);
     $transactionService = new PaypalTransaction();
     $transaction = $transactionService->getTransactionById($myPost['txn_id']);
     if ($transaction === null) {
         $extraService = $this->getExtraService($myPost);
         if ($this->validateTransaction($myPost, $extraService)) {
             // @TODO remake this
             $relationId = $this->createRelation($extraService, $userId, $myPost['quantity']);
             $myPost['relation_id'] = $relationId;
             $myPost['relation_type'] = $transactionService::TRANSACTION_RELATION_EXTRA_SERVICE;
             $transactionService->createTransaction($myPost);
             self::log(['message' => "Success. Payment processed", 'level' => self::LOG_LEVEL_INFO], $myPost);
         }
     } else {
         self::log(['message' => "Duplicate. Transaction {$myPost['txn_id']} already processed", 'level' => self::LOG_LEVEL_WARNING], $myPost);
     }
 }
 /**
  * Save the transaction data in the database
  *
  * @return void
  */
 private function saveTransaction()
 {
     $this->debug('Saving IPN as transaction');
     $transaction = new PaypalTransaction();
     $transaction->parent_id = $this->getRelatedEntity() ? $this->getRelatedEntity()->id : null;
     $transaction->txn_id = $this['txn_id'];
     $transaction->txn_type = $this['txn_type'];
     $transaction->status = $this['payment_status'];
     $transaction->ipn_data = serialize($this->ipnData);
     $transaction->save();
     return $transaction;
 }
 /**
  * @param $myPost
  * @throws Exception
  */
 public function processPayment($myPost)
 {
     $customData = $this->getCustomData($myPost);
     $userId = $customData['user_id'];
     $userService = new UserService();
     $userInfo = $userService->getUserData($userId);
     $userEmail = $userInfo['email'];
     $subscriptionPlan = $this->getSubscriptionPlan($myPost);
     if ($this->validateSubscription($subscriptionPlan, $myPost)) {
         $subscription = new Subscription();
         $subscription->loadBySubscriptionId($myPost['subscr_id']);
         $transactionService = new PaypalTransaction();
         $transaction = $transactionService->getTransactionById($myPost['txn_id']);
         if ($subscription->id) {
             //subscription exists
             if ($myPost['txn_type'] == 'subscr_payment') {
                 if (!$transaction) {
                     $subscription->status = Subscription::STATUS_ACTIVE;
                     $subscription->payment_date = $myPost['payment_date'];
                     $subscription->updated_date = date('Y-m-d H:i:s');
                     $subscription->save();
                     self::log(['message' => self::INFO_SUBSCRIPTION_PAYMENT, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
                     $myPost['relation_id'] = $subscription->id;
                     //@TODO remake it
                     $transactionService = new PaypalTransaction();
                     $myPost['relation_type'] = PaypalTransaction::TRANSACTION_RELATION_SUBSCRIPTION;
                     $transactionService->createTransaction($myPost);
                     self::log(['message' => self::INFO_TRANSACTION_CREATED, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
                 } else {
                     self::log(['message' => self::WARNING_DUPLICATE_TRANSACTION_IPN, 'data' => '', 'level' => self::LOG_LEVEL_WARNING], $myPost);
                 }
             }
             if ($myPost['txn_type'] == 'subscr_cancel') {
                 $subscription->status = Subscription::STATUS_CANCELED;
                 $subscription->updated_date = date('Y-m-d H:i:s');
                 $subscription->save();
                 self::log(['message' => self::INFO_SUBSCRIPTION_CANCELED, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
             }
             if ($myPost['txn_type'] == 'subscr_eot') {
                 $subscription->status = Subscription::STATUS_CANCELED;
                 $subscription->updated_date = date('Y-m-d H:i:s');
                 $subscription->save();
                 self::log(['message' => self::INFO_SUBSCRIPTION_EXPIRED, 'level' => self::LOG_LEVEL_WARNING], $myPost);
             }
             if ($myPost['txn_type'] == 'subscr_signup') {
                 self::log(['message' => self::INFO_SUBSCRIPTION_SIGNUP, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
             }
             if ($myPost['txn_type'] == 'subscr_modify') {
                 $subscription->status = Subscription::STATUS_CANCELED;
                 $subscription->updated_date = date('Y-m-d H:i:s');
                 $subscription->save();
                 self::log(['message' => self::INFO_SUBSCRIPTION_MODIFIED, 'level' => self::LOG_LEVEL_WARNING], $myPost);
             }
             if ($myPost['payment_status'] == 'Refunded' && $myPost['reason_code'] == 'refund') {
                 //refund transaction
                 $transactionService = new PaypalTransaction();
                 $transactionService->updateTransaction($myPost['parent_txn_id'], ['payment_status' => 'Refunded']);
                 $myPost['txn_type'] = self::TXN_TYPE_SUBSCR_REFUND;
                 $myPost['relation_id'] = $subscription->id;
                 //@TODO refactor this
                 $myPost['relation_type'] = PaypalTransaction::TRANSACTION_RELATION_SUBSCRIPTION;
                 $transactionService = new PaypalTransaction();
                 $transactionService->createTransaction($myPost);
                 self::log(['message' => self::INFO_PAYMENT_REFUND, 'level' => self::LOG_LEVEL_INFO], $myPost);
             }
         } else {
             if ($myPost['txn_type'] == 'subscr_payment') {
                 //@TODO remake it
                 $serviceProvider = $subscriptionPlan->service_provider;
                 $activeSubscriptions = Subscription::getActiveSubscriptions($userId, $serviceProvider);
                 /* check duplicate subscriptions*/
                 if (count($activeSubscriptions) > 0) {
                     self::log(['message' => self::ERROR_ACTIVE_SUBSCRIPTION_DUPLICATE, 'level' => self::LOG_LEVEL_ERROR], $myPost);
                 } elseif (!$transaction) {
                     $subscription = new Subscription();
                     $subscription->user_id = $userId;
                     $subscription->plan_id = $subscriptionPlan->id;
                     $subscription->subscription_id = $myPost['subscr_id'];
                     $subscription->created_date = date("Y-m-d H:i:s");
                     $subscription->updated_date = date('Y-m-d H:i:s');
                     $subscription->payment_date = $myPost['payment_date'];
                     $subscription->items_count = $customData['items_count'];
                     $subscription->status = Subscription::STATUS_ACTIVE;
                     $subscriptionId = $subscription->save();
                     self::log(['message' => self::INFO_SUBSCRIPTION_CREATED, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
                     $myPost['relation_id'] = $subscriptionId;
                     //@TODO refactor this
                     $myPost['relation_type'] = PaypalTransaction::TRANSACTION_RELATION_SUBSCRIPTION;
                     $transactionService = new PaypalTransaction();
                     $transactionService->createTransaction($myPost);
                     self::log(['message' => self::INFO_TRANSACTION_CREATED, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
                 } else {
                     self::log(['message' => self::WARNING_DUPLICATE_TRANSACTION_IPN, 'data' => '', 'level' => self::LOG_LEVEL_WARNING], $myPost);
                 }
             }
             if ($myPost['txn_type'] == 'subscr_signup') {
                 self::log(['message' => self::INFO_SUBSCRIPTION_SIGNUP, 'data' => '', 'level' => self::LOG_LEVEL_INFO], $myPost);
             }
             if ($myPost['txn_type'] == 'subscr_modify') {
                 self::log(['message' => self::INFO_SUBSCRIPTION_MODIFIED, 'level' => self::LOG_LEVEL_WARNING], $myPost);
             }
         }
     } else {
         self::log(['message' => self::VALIDATION_FAILED, 'level' => self::LOG_LEVEL_ERROR], $myPost);
         echo self::VALIDATION_FAILED;
         die;
     }
 }