/**
  * Private utility function for function updatePaymentStatus(): Stores only once the completed payment for a given transaction id of a $notification
  *
  * @param  cbpaidPaymentBasket        $paymentBasket
  * @param  cbpaidPaymentNotification  $notification               notification object of the payment
  * @param  int                        $now
  * @param  boolean|string             $txnIdMultiplePaymentDates  FALSE: unique txn_id for each payment, TRUE: same txn_id can have multiple payment dates, additionally: 'singlepayment' will not look at txn_id at all
  * @param  string                     $updateMessage              Message for the history log for the payment when storing to database
  * @return boolean                                          TRUE: This is really a new payment, FALSE: no, we already received and recorded it (e.g. IPN before PDT)
  */
 private function _storePaymentOnce(&$paymentBasket, &$notification, $now, $txnIdMultiplePaymentDates, $updateMessage)
 {
     global $_CB_database;
     $payment = new cbpaidPayment($_CB_database);
     $whereArray = array('payment_basket_id' => (int) $paymentBasket->id, 'mc_gross' => (string) $notification->mc_gross);
     if ($notification->txn_id !== null && $txnIdMultiplePaymentDates !== 'singlepayment') {
         $whereArray['txn_id'] = (string) $notification->txn_id;
     }
     if ($txnIdMultiplePaymentDates === true) {
         $whereArray['payment_date'] = (string) $notification->payment_date;
     }
     $entry_exists = $payment->loadThisMatching($whereArray, array('id' => 'ASC'));
     $iAmReferencePayment = !$entry_exists || !in_array($payment->payment_status, array('Completed', 'Processed'));
     if ($iAmReferencePayment) {
         // now here we could be at this same place with 2 processes ! if IPN and PDT happen exactly same time (it happens!)
         if ($notification->payment_date) {
             $paymentDate = Application::Database()->getUtcDateTime(cbpaidTimes::getInstance()->gmStrToTime($notification->payment_date));
         } else {
             $paymentDate = $paymentBasket->time_completed;
         }
         $payment->bindPayment($paymentBasket, $notification, $paymentDate, $now);
         $payment->historySetMessage($updateMessage);
         $payment->store();
     }
     if (!$entry_exists && $iAmReferencePayment) {
         // we had to insert a new payment entry: check that it's not duplicate due to simultaneous asynchronous IPN with PDT
         $allPayments = $payment->loadThisMatchingList($whereArray);
         if (count($allPayments) !== 1) {
             if ($payment->id != min(array_keys($allPayments))) {
                 // oops! it really happened: return that we are not the one which should change anything, and delete our duplicate record:
                 $iAmReferencePayment = false;
                 $payment->delete();
             }
             // it happened, but we are the wining payment...
         }
     }
     return $iAmReferencePayment;
 }