public TransferPaidResponseDTO TransferPaid(DateTime?eventTimestamp, StripeTransfer transfer)
        {
            _logger.Debug("Processing transfer.paid event for transfer id " + transfer.Id);

            var response = new TransferPaidResponseDTO();

            // Don't process this transfer if we already have a deposit for the same transfer id
            var existingDeposit = _donationService.GetDepositByProcessorTransferId(transfer.Id);

            if (existingDeposit != null)
            {
                var msg = $"Deposit {existingDeposit.Id} already created for transfer {existingDeposit.ProcessorTransferId}";
                _logger.Debug(msg);
                response.TotalTransactionCount = 0;
                response.Message   = msg;
                response.Exception = new ApplicationException(msg);
                return(response);
            }

            // Don't process this transfer if we can't find any charges for the transfer
            var charges = _paymentProcessorService.GetChargesForTransfer(transfer.Id);

            if (charges == null || charges.Count <= 0)
            {
                var msg = "No charges found for transfer: " + transfer.Id;
                _logger.Debug(msg);
                response.TotalTransactionCount = 0;
                response.Message   = msg;
                response.Exception = new ApplicationException(msg);
                return(response);
            }

            var depositName = DateTime.Now.ToString(BatchNameDateFormat);

            var paymentcharges  = charges.Where(m => m.Metadata != null && m.Metadata.ContainsKey("crossroads_transaction_type") && m.Metadata["crossroads_transaction_type"].ToString() == "payment").ToList();
            var donationcharges = charges.Except(paymentcharges).ToList();

            if (paymentcharges.Count + donationcharges.Count != charges.Count)
            {
                var msg = "Donation and Payment charges count error for transfer: " + transfer.Id;
                _logger.Debug(msg);
                response.TotalTransactionCount = 0;
                response.Message   = msg;
                response.Exception = new ApplicationException(msg);
                return(response);
            }

            var paymentBatch  = CreateBatchDTOFromCharges(paymentcharges, depositName + "P", eventTimestamp, transfer, ref response);
            var donationBatch = CreateBatchDTOFromCharges(donationcharges, depositName + "D", eventTimestamp, transfer, ref response);

            var stripeTotalFees = paymentBatch.BatchFeeTotal + donationBatch.BatchFeeTotal;

            // Create the deposit
            var deposit = new DepositDTO
            {
                // Account number must be non-null, and non-empty; using a single space to fulfill this requirement
                AccountNumber   = " ",
                BatchCount      = paymentBatch.ItemCount > 0 && donationBatch.ItemCount > 0 ? 2 : 1,
                DepositDateTime = DateTime.Now,
                DepositName     = depositName,
                // This is the amount from Stripe - will show out of balance if does not match batch total above
                DepositTotalAmount = ((transfer.Amount / Constants.StripeDecimalConversionValue) + (stripeTotalFees / Constants.StripeDecimalConversionValue)),
                ProcessorFeeTotal  = stripeTotalFees / Constants.StripeDecimalConversionValue,
                DepositAmount      = transfer.Amount / Constants.StripeDecimalConversionValue,
                Exported           = false,
                Notes = null,
                ProcessorTransferId = transfer.Id
            };

            try
            {
                response.Deposit = _donationService.CreateDeposit(deposit);
            }
            catch (Exception e)
            {
                _logger.Error("Failed to create batch deposit", e);
                throw;
            }

            // Create the batch, with the above deposit id
            paymentBatch.DepositId  = response.Deposit.Id;
            donationBatch.DepositId = response.Deposit.Id;

            //donation Batch
            try
            {
                if (donationBatch.ItemCount > 0)
                {
                    response.Batch.Add(_donationService.CreateDonationBatch(donationBatch));
                }
            }
            catch (Exception e)
            {
                _logger.Error("Failed to create donation batch", e);
                throw;
            }

            // payment Batch
            try
            {
                if (paymentBatch.ItemCount > 0)
                {
                    response.Batch.Add(_paymentService.CreatePaymentBatch(paymentBatch));
                }
            }
            catch (Exception e)
            {
                _logger.Error("Failed to create payment batch", e);
                throw;
            }

            return(response);
        }