docs: def processPayment(self, amount, fees, paidOnline=True, methodName=None, methodTxn=None, submissionUser=None, collectedByUser=None, forceFinalize=False, status=None, notify=None):
          '''
          When a payment processor makes a successful payment against an invoice, it can call this method
          which handles status updates, the creation of a final registration object (if applicable), and
          the firing of appropriate registration-related signals.
          '''
          epsilon = .01
  
          paymentTime = timezone.now()
  
          logger.info('Processing payment and creating registration objects if applicable.')
  
          # The payment history record is primarily for convenience, and passed values are not
          # validated.  Payment processing apps should keep individual transaction records with
          # a ForeignKey to the Invoice object.
          paymentHistory = self.data.get('paymentHistory',[])
          paymentHistory.append({
              'dateTime': paymentTime.isoformat(),
              'amount': amount,
              'fees': fees,
              'paidOnline': paidOnline,
              'methodName': methodName,
              'methodTxn': methodTxn,
              'submissionUser': getattr(submissionUser,'id',None),
              'collectedByUser': getattr(collectedByUser,'id',None),
          })
          self.data['paymentHistory'] = paymentHistory
  
          self.amountPaid += amount
          self.fees += fees
          self.paidOnline = paidOnline
  
          if submissionUser and not self.submissionUser:
              self.submissionUser = submissionUser
          if collectedByUser and not self.collectedByUser:
              self.collectedByUser = collectedByUser
  
          # if this completed the payment, then finalize the registration and mark
          # the invoice as Paid unless told to do otherwise.
          if forceFinalize or abs(self.outstandingBalance) < epsilon:
              self.status = status or self.PaymentStatus.paid
              if not self.finalRegistration and self.temporaryRegistration:
                  self.finalRegistration = self.temporaryRegistration.finalize(dateTime=paymentTime)
              else:
                  self.sendNotification(invoicePaid=True,thisPaymentAmount=amount,payerEmail=notify)
              self.save()
              if self.finalRegistration:
                  for eventReg in self.finalRegistration.eventregistration_set.filter(cancelled=False):
                      # There can only be one eventreg per event in a registration, so we
                      # can filter on temporaryRegistration event to get the invoiceItem
                      # to which we should attach a finalEventRegistration
                      this_invoice_item = self.invoiceitem_set.filter(
                          temporaryEventRegistration__event=eventReg.event,
                          finalEventRegistration__isnull=True
                      ).first()
                      if this_invoice_item:
                          this_invoice_item.finalEventRegistration = eventReg
                          this_invoice_item.save()
          else:
              # The payment wasn't completed so don't finalize, but do send a notification recording the payment.
              if notify:
                  self.sendNotification(invoicePaid=True,thisPaymentAmount=amount,payerEmail=notify)
              else:
                  self.sendNotification(invoicePaid=True,thisPaymentAmount=amount)
              self.save()
  
          # If there were transaction fees, then these also need to be allocated among the InvoiceItems
          # All fees from payments are allocated proportionately.
          self.allocateFees()