예제 #1
0
        public int?CreateDonationForInvoice(StripeInvoice invoice)
        {
            if (string.IsNullOrWhiteSpace(invoice.Charge) || invoice.Amount <= 0)
            {
                _logger.Info(string.Format("No charge or amount on invoice {0} for subscription {1} - this is likely a trial-period donation, skipping", invoice.Id, invoice.Subscription));
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug(string.Format("Invoice: {0}", JsonConvert.SerializeObject(invoice)));
                }
                return(null);
            }

            // Make sure we don't create duplicate donations for the same charge (could happen if we get a transfer and a invoice.payment_succeeded events near each other
            try
            {
                var donation = _mpDonationRepository.GetDonationByProcessorPaymentId(invoice.Charge);
                if (donation != null)
                {
                    _logger.Info(string.Format("Donation already located for charge id {0}, not creating duplicate (existing donation {1})", invoice.Charge, donation.donationId));
                    return(donation.donationId);
                }
            }
            catch (DonationNotFoundException)
            {
                _logger.Info(string.Format("Donation not located for charge id {0}, this is expected", invoice.Charge));
            }

            var charge         = _paymentService.GetCharge(invoice.Charge);
            var createDonation = _mpDonorRepository.GetRecurringGiftForSubscription(invoice.Subscription, charge.ProcessorId);

            _mpDonorRepository.UpdateRecurringGiftFailureCount(createDonation.RecurringGiftId.Value, Constants.ResetFailCount);

            var donationStatus = charge.Status == "succeeded" ? DonationStatus.Succeeded : DonationStatus.Pending;
            var fee            = charge.BalanceTransaction != null ? charge.BalanceTransaction.Fee : null;
            var amount         = charge.Amount / Constants.StripeDecimalConversionValue;

            var donationAndDistribution = new MpDonationAndDistributionRecord
            {
                DonationAmt     = amount,
                FeeAmt          = fee,
                DonorId         = createDonation.DonorId,
                ProgramId       = createDonation.ProgramId,
                ChargeId        = invoice.Charge,
                PymtType        = createDonation.PaymentType,
                ProcessorId     = invoice.Customer,
                SetupDate       = invoice.Date,
                RegisteredDonor = true,
                RecurringGift   = true,
                RecurringGiftId = createDonation.RecurringGiftId,
                DonorAcctId     = createDonation.DonorAccountId.HasValue ? createDonation.DonorAccountId.ToString() : null,
                DonationStatus  = (int)donationStatus
            };

            return(_mpDonorRepository.CreateDonationAndDistributionRecord(donationAndDistribution, false));
        }
예제 #2
0
        public MpPaymentDetailReturn PostPayment(MpDonationAndDistributionRecord paymentRecord)
        {
            //check if invoice exists
            if (!_invoiceRepository.InvoiceExists(paymentRecord.InvoiceId))
            {
                throw new InvoiceNotFoundException(paymentRecord.InvoiceId);
            }

            //check if contact exists
            if (_contactRepository.GetContactById(paymentRecord.ContactId) == null)
            {
                throw new ContactNotFoundException(paymentRecord.ContactId);
            }

            if (paymentRecord.ProcessorId.Length > 50)
            {
                throw new Exception("Max length of 50 exceeded for transaction code");
            }

            var pymtId = PaymentType.GetPaymentType(paymentRecord.PymtType).id;
            var fee    = paymentRecord.FeeAmt.HasValue ? paymentRecord.FeeAmt / Constants.StripeDecimalConversionValue : null;

            //check if payment type exists
            if (!_paymentTypeRepository.PaymentTypeExists(pymtId))
            {
                throw new PaymentTypeNotFoundException(pymtId);
            }

            //create payment -- send model
            var payment = new MpPayment
            {
                InvoiceNumber      = paymentRecord.InvoiceId.ToString(),
                ContactId          = paymentRecord.ContactId,
                TransactionCode    = paymentRecord.ProcessorId,
                PaymentDate        = DateTime.Now,
                PaymentTotal       = paymentRecord.DonationAmt,
                PaymentTypeId      = pymtId,
                PaymentStatus      = _defaultPaymentStatus,
                ProcessorFeeAmount = fee
            };
            var paymentDetail = new MpPaymentDetail
            {
                Payment         = payment,
                PaymentAmount   = paymentRecord.DonationAmt,
                InvoiceDetailId = _invoiceRepository.GetInvoiceDetailForInvoice(paymentRecord.InvoiceId).InvoiceDetailId
            };

            var result = _paymentRepository.CreatePaymentAndDetail(paymentDetail);

            if (result.Status)
            {
                //update invoice payment status
                var invoice  = _invoiceRepository.GetInvoice(paymentRecord.InvoiceId);
                var payments = _paymentRepository.GetPaymentsForInvoice(paymentRecord.InvoiceId);
                payments = payments.Where(p => p.PaymentStatus != _declinedPaymentStatus).ToList();
                var paymentTotal = payments.Sum(p => p.PaymentTotal);

                _invoiceRepository.SetInvoiceStatus(paymentRecord.InvoiceId, paymentTotal >= invoice.InvoiceTotal ? _paidinfullStatus : _somepaidStatus);
                return(result.Value);
            }
            else
            {
                throw new Exception("Unable to save payment data");
            }
        }
예제 #3
0
        public int CreateDonationAndDistributionRecord(MpDonationAndDistributionRecord donationAndDistribution, bool sendConfirmationEmail = true)
        {
            var pymtId = PaymentType.GetPaymentType(donationAndDistribution.PymtType).id;
            var fee    = donationAndDistribution.FeeAmt.HasValue ? donationAndDistribution.FeeAmt / Constants.StripeDecimalConversionValue : null;

            var apiToken = ApiLogin();

            var donationValues = new Dictionary <string, object>
            {
                { "Donor_ID", donationAndDistribution.DonorId },
                { "Donation_Amount", donationAndDistribution.DonationAmt },
                { "Processor_Fee_Amount", fee },
                { "Payment_Type_ID", pymtId },
                { "Donation_Date", donationAndDistribution.SetupDate },
                { "Transaction_code", donationAndDistribution.ChargeId },
                { "Registered_Donor", donationAndDistribution.RegisteredDonor },
                { "Anonymous", donationAndDistribution.Anonymous },
                { "Processor_ID", donationAndDistribution.ProcessorId },
                { "Donation_Status_Date", donationAndDistribution.SetupDate },
                { "Donation_Status_ID", donationAndDistribution.DonationStatus ?? 1 }, //hardcoded to pending if no status specified
                { "Recurring_Gift_ID", donationAndDistribution.RecurringGiftId },
                { "Is_Recurring_Gift", donationAndDistribution.RecurringGift },
                { "Donor_Account_ID", donationAndDistribution.DonorAcctId },
                { "Source_Url", donationAndDistribution.SourceUrl },
                { "Predefined_Amount", donationAndDistribution.PredefinedAmount },
            };

            if (!string.IsNullOrWhiteSpace(donationAndDistribution.CheckScannerBatchName))
            {
                donationValues["Check_Scanner_Batch"] = donationAndDistribution.CheckScannerBatchName;
            }

            if (!string.IsNullOrWhiteSpace(donationAndDistribution.CheckNumber))
            {
                donationValues["Item_Number"] = donationAndDistribution.CheckNumber;
            }

            if (!string.IsNullOrWhiteSpace(donationAndDistribution.Notes))
            {
                donationValues["Notes"] = donationAndDistribution.Notes;
            }

            int donationId;

            try
            {
                donationId = _ministryPlatformService.CreateRecord(_donationPageId, donationValues, apiToken, true);
            }
            catch (Exception e)
            {
                throw new ApplicationException(string.Format("CreateDonationRecord failed.  Donor Id: {0}", donationAndDistribution.DonorId), e);
            }

            if (donationAndDistribution.HasDistributions)
            {
                foreach (var distribution in donationAndDistribution.Distributions)
                {
                    CreateDistributionRecord(donationId,
                                             distribution.donationDistributionAmt / Constants.StripeDecimalConversionValue,
                                             distribution.donationDistributionProgram,
                                             distribution.PledgeId,
                                             apiToken);
                }
            }
            else if (string.IsNullOrWhiteSpace(donationAndDistribution.ProgramId))
            {
                return(donationId);
            }
            else
            {
                CreateDistributionRecord(donationId, donationAndDistribution.DonationAmt, donationAndDistribution.ProgramId, donationAndDistribution.PledgeId, apiToken);
            }

            if (!sendConfirmationEmail)
            {
                return(donationId);
            }

            if (sendConfirmationEmail)
            {
                try
                {
                    SetupConfirmationEmail(Convert.ToInt32(donationAndDistribution.ProgramId), donationAndDistribution.DonorId, donationAndDistribution.DonationAmt, donationAndDistribution.SetupDate, donationAndDistribution.PymtType, donationAndDistribution.PledgeId ?? 0);
                }
                catch (Exception e)
                {
                    _logger.Error(string.Format("Failed when processing the template for Donation Id: {0}", donationId), e);
                }
            }

            return(donationId);
        }
        private IHttpActionResult CreateDonationAndDistributionUnauthenticated(CreateDonationDTO dto)
        {
            bool isPayment = false;

            try
            {
                var donor    = _gatewayDonorService.GetContactDonorForEmail(dto.EmailAddress);
                var charge   = _stripeService.ChargeCustomer(donor.ProcessorId, dto.Amount, donor.DonorId, isPayment);
                var fee      = charge.BalanceTransaction != null ? charge.BalanceTransaction.Fee : null;
                int?pledgeId = null;
                if (dto.PledgeCampaignId != null && dto.PledgeDonorId != null)
                {
                    var pledge = _mpPledgeService.GetPledgeByCampaignAndDonor(dto.PledgeCampaignId.Value, dto.PledgeDonorId.Value);
                    if (pledge != null)
                    {
                        pledgeId = pledge.PledgeId;
                    }
                }

                var donationAndDistribution = new MpDonationAndDistributionRecord
                {
                    DonationAmt      = dto.Amount,
                    FeeAmt           = fee,
                    DonorId          = donor.DonorId,
                    ProgramId        = dto.ProgramId,
                    PledgeId         = pledgeId,
                    ChargeId         = charge.Id,
                    PymtType         = dto.PaymentType,
                    ProcessorId      = donor.ProcessorId,
                    SetupDate        = DateTime.Now,
                    RegisteredDonor  = false,
                    Anonymous        = dto.Anonymous,
                    PredefinedAmount = dto.PredefinedAmount,
                    SourceUrl        = dto.SourceUrl
                };

                var donationId = _mpDonorService.CreateDonationAndDistributionRecord(donationAndDistribution);
                if (!dto.GiftMessage.IsNullOrWhiteSpace() && pledgeId != null)
                {
                    SendMessageFromDonor(pledgeId.Value, donationId, dto.GiftMessage);
                }

                var response = new DonationDTO()
                {
                    ProgramId = dto.ProgramId,
                    Amount    = (int)dto.Amount,
                    Id        = donationId.ToString(),
                    Email     = donor.Email
                };

                return(Ok(response));
            }
            catch (PaymentProcessorException stripeException)
            {
                return(stripeException.GetStripeResult());
            }
            catch (Exception exception)
            {
                var apiError = new ApiErrorDto("Donation Post Failed", exception);
                throw new HttpResponseException(apiError.HttpResponseMessage);
            }
        }
        private IHttpActionResult CreateDonationAndDistributionAuthenticated(String token, CreateDonationDTO dto)
        {
            var isPayment = (dto.TransactionType != null && dto.TransactionType.Equals("PAYMENT"));

            try
            {
                if (isPayment)
                {
                    //check if invoice exists before create Stripe Charge
                    if (dto.InvoiceId != null && !_invoiceRepository.InvoiceExists(dto.InvoiceId.Value))
                    {
                        var apiError = new ApiErrorDto("Invoice Not Found", new InvoiceNotFoundException(dto.InvoiceId.Value));
                        throw new HttpResponseException(apiError.HttpResponseMessage);
                    }
                }

                var contactId = _authenticationService.GetContactId(token);
                var donor     = _mpDonorService.GetContactDonor(contactId);
                var charge    = _stripeService.ChargeCustomer(donor.ProcessorId, dto.Amount, donor.DonorId, isPayment);
                var fee       = charge.BalanceTransaction != null ? charge.BalanceTransaction.Fee : null;

                int?pledgeId = null;
                if (dto.PledgeCampaignId != null && dto.PledgeDonorId != null)
                {
                    var pledge = _mpPledgeService.GetPledgeByCampaignAndDonor(dto.PledgeCampaignId.Value, dto.PledgeDonorId.Value);
                    if (pledge != null)
                    {
                        pledgeId = pledge.PledgeId;
                    }
                }

                if (!isPayment)
                {
                    var donationAndDistribution = new MpDonationAndDistributionRecord
                    {
                        DonationAmt      = dto.Amount,
                        FeeAmt           = fee,
                        DonorId          = donor.DonorId,
                        ProgramId        = dto.ProgramId,
                        PledgeId         = pledgeId,
                        ChargeId         = charge.Id,
                        PymtType         = dto.PaymentType,
                        ProcessorId      = donor.ProcessorId,
                        SetupDate        = DateTime.Now,
                        RegisteredDonor  = true,
                        Anonymous        = dto.Anonymous,
                        SourceUrl        = dto.SourceUrl,
                        PredefinedAmount = dto.PredefinedAmount
                    };

                    var donationId = _mpDonorService.CreateDonationAndDistributionRecord(donationAndDistribution, !dto.TripDeposit);
                    if (!dto.GiftMessage.IsNullOrWhiteSpace() && pledgeId != null)
                    {
                        SendMessageFromDonor(pledgeId.Value, donationId, dto.GiftMessage);
                    }
                    var response = new DonationDTO
                    {
                        ProgramId = dto.ProgramId,
                        Amount    = (int)dto.Amount,
                        Id        = donationId.ToString(),
                        Email     = donor.Email
                    };

                    return(Ok(response));
                }
                else //Payment flow (non-contribution transaction)
                {
                    if (!ModelState.IsValid)
                    {
                        var errors    = ModelState.Values.SelectMany(val => val.Errors).Aggregate("", (current, err) => current + err.Exception.Message);
                        var dataError = new ApiErrorDto("Payment data Invalid", new InvalidOperationException("Invalid Payment Data" + errors));
                        throw new HttpResponseException(dataError.HttpResponseMessage);
                    }

                    try
                    {
                        var invoiceId = dto.InvoiceId != null ? dto.InvoiceId.Value : 0;
                        var payment   = new MpDonationAndDistributionRecord
                        {
                            DonationAmt = dto.Amount,
                            PymtType    = dto.PaymentType,
                            ProcessorId = charge.Id,
                            ContactId   = contactId,
                            InvoiceId   = invoiceId,
                            FeeAmt      = fee
                        };
                        var paymentReturn = _paymentService.PostPayment(payment);
                        var response      = new DonationDTO
                        {
                            Amount    = (int)dto.Amount,
                            Email     = donor.Email,
                            PaymentId = paymentReturn.PaymentId
                        };
                        return(Ok(response));
                    }
                    catch (InvoiceNotFoundException e)
                    {
                        var apiError = new ApiErrorDto("Invoice Not Found", e);
                        throw new HttpResponseException(apiError.HttpResponseMessage);
                    }
                    catch (ContactNotFoundException e)
                    {
                        var apiError = new ApiErrorDto("Contact Not Found", e);
                        throw new HttpResponseException(apiError.HttpResponseMessage);
                    }
                    catch (PaymentTypeNotFoundException e)
                    {
                        var apiError = new ApiErrorDto("PaymentType Not Found", e);
                        throw new HttpResponseException(apiError.HttpResponseMessage);
                    }
                    catch (Exception e)
                    {
                        var apiError = new ApiErrorDto("SavePayment Failed", e);
                        throw new HttpResponseException(apiError.HttpResponseMessage);
                    }
                }
            }
            catch (PaymentProcessorException stripeException)
            {
                return(stripeException.GetStripeResult());
            }
            catch (Exception exception)
            {
                var apiError = new ApiErrorDto("Donation/Payment Post Failed", exception);
                throw new HttpResponseException(apiError.HttpResponseMessage);
            }
        }
예제 #6
0
        private IHttpActionResult CreateDonationAndDistributionUnauthenticated(CreateDonationDTO dto)
        {
            bool           isPayment = false;
            MpContactDonor donor     = null;

            try
            {
                donor = _gatewayDonorService.GetContactDonorForEmail(dto.EmailAddress);
                var charge   = _stripeService.ChargeCustomer(donor.ProcessorId, dto.Amount, donor.DonorId, isPayment);
                var fee      = charge.BalanceTransaction != null ? charge.BalanceTransaction.Fee : null;
                int?pledgeId = null;
                if (dto.PledgeCampaignId != null && dto.PledgeDonorId != null)
                {
                    var pledge = _mpPledgeService.GetPledgeByCampaignAndDonor(dto.PledgeCampaignId.Value, dto.PledgeDonorId.Value);
                    if (pledge != null)
                    {
                        pledgeId = pledge.PledgeId;
                    }
                }

                var donationAndDistribution = new MpDonationAndDistributionRecord
                {
                    DonationAmt      = dto.Amount,
                    FeeAmt           = fee,
                    DonorId          = donor.DonorId,
                    ProgramId        = dto.ProgramId,
                    PledgeId         = pledgeId,
                    ChargeId         = charge.Id,
                    PymtType         = dto.PaymentType,
                    ProcessorId      = donor.ProcessorId,
                    SetupDate        = DateTime.Now,
                    RegisteredDonor  = false,
                    Anonymous        = dto.Anonymous,
                    PredefinedAmount = dto.PredefinedAmount,
                    SourceUrl        = dto.SourceUrl
                };

                var from = dto.Anonymous ? "Anonymous" : donor.Details.FirstName + " " + donor.Details.LastName;

                var donationId = _mpDonorService.CreateDonationAndDistributionRecord(donationAndDistribution);
                if (!dto.GiftMessage.IsNullOrWhiteSpace() && pledgeId != null)
                {
                    SendMessageFromDonor(pledgeId.Value, donationId, dto.GiftMessage, from);
                }

                var response = new DonationDTO()
                {
                    ProgramId = dto.ProgramId,
                    Amount    = (int)dto.Amount,
                    Id        = donationId.ToString(),
                    Email     = donor.Email
                };

                _analyticsService.Track(donor.ContactId.ToString(), "PaymentSucceededServerSide", new EventProperties()
                {
                    { "Url", dto.SourceUrl }, { "FundingMethod", dto.PaymentType }, { "Email", donor.Email }, { "CheckoutType", "Guest" }, { "Amount", dto.Amount }
                });
                return(Ok(response));
            }
            catch (PaymentProcessorException stripeException)
            {
                LogDonationError("CreateDonationAndDistributionUnauthenticated", stripeException, dto, donor);
                return(stripeException.GetStripeResult());
            }
            catch (Exception exception)
            {
                LogDonationError("CreateDonationAndDistributionUnauthenticated", exception, dto, donor);
                var apiError = new ApiErrorDto("Donation Post Failed", exception);
                throw new HttpResponseException(apiError.HttpResponseMessage);
            }
        }
예제 #7
0
        public int?CreateDonationForBankAccountErrorRefund(StripeRefund refund)
        {
            if (refund.Data[0].BalanceTransaction == null || !"payment_failure_refund".Equals(refund.Data[0].BalanceTransaction.Type))
            {
                _logger.Error(string.Format("Balance transaction was not set, or was not a payment_failure_refund for refund ID {0}", refund.Data[0].Id));
                return(null);
            }

            if (refund.Data[0].Charge == null || string.IsNullOrWhiteSpace(refund.Data[0].Charge.Id))
            {
                _logger.Error(string.Format("No associated Charge for Refund {0}", refund.Data[0].Id));
                return(null);
            }

            MpDonation donation;

            try
            {
                donation = _mpDonationRepository.GetDonationByProcessorPaymentId(refund.Data[0].Charge.Id, true);
            }
            catch (DonationNotFoundException)
            {
                _logger.Error(string.Format("No Donation with payment processor ID {0} in MP for Refund {1}", refund.Data[0].Charge.Id, refund.Data[0].Id));
                return(null);
            }

            var donationAndDist = new MpDonationAndDistributionRecord
            {
                Anonymous             = false,
                ChargeId              = refund.Data[0].Id,
                CheckNumber           = null,
                CheckScannerBatchName = null,
                DonationAmt           = -(int.Parse(refund.Data[0].Amount) / Constants.StripeDecimalConversionValue),
                DonationStatus        = (int)DonationStatus.Declined,
                DonorAcctId           = string.Empty,
                DonorId         = _bankErrorRefundDonorId,
                FeeAmt          = refund.Data[0].BalanceTransaction.Fee,
                PledgeId        = null,
                RecurringGift   = false,
                ProcessorId     = string.Empty,
                ProgramId       = donation.Distributions[0].donationDistributionProgram,
                PymtType        = MinistryPlatform.Translation.Enum.PaymentType.GetPaymentType(donation.paymentTypeId).name,
                RecurringGiftId = null,
                RegisteredDonor = false,
                SetupDate       = refund.Data[0].BalanceTransaction.Created,
                Notes           = string.Format("Reversed from DonationID {0}", donation.donationId)
            };

            foreach (var distribution in donation.Distributions)
            {
                donationAndDist.Distributions.Add(new MpDonationDistribution
                {
                    donationDistributionAmt     = -distribution.donationDistributionAmt,
                    donationDistributionProgram = distribution.donationDistributionProgram,
                    PledgeId = distribution.PledgeId
                });
            }

            // Create the refund donation and distribution(s), but do NOT send email
            return(_mpDonorRepository.CreateDonationAndDistributionRecord(donationAndDist, false));
        }
예제 #8
0
        public CheckScannerBatch CreateDonationsForBatch(CheckScannerBatch batchDetails)
        {
            var checks = _checkScannerDao.GetChecksForBatch(batchDetails.Name);

            foreach (var check in checks)
            {
                if (check.Exported)
                {
                    var previousError = string.IsNullOrWhiteSpace(check.Error) ? string.Empty : string.Format("Previous Error: {0}", check.Error);
                    var msg           = string.Format("Not exporting check {0} on batch {1}, it was already exported. {2}", check.Id, batchDetails.Name, previousError);
                    _logger.Info(msg);
                    check.Error = msg;
                    batchDetails.ErrorChecks.Add(check);
                    continue;
                }

                try
                {
                    var contactDonor = CreateDonor(check);

                    var account      = _mpDonorService.DecryptCheckValue(check.AccountNumber);
                    var routing      = _mpDonorService.DecryptCheckValue(check.RoutingNumber);
                    var encryptedKey = _mpDonorService.CreateHashedAccountAndRoutingNumber(account, routing);

                    string donorAccountId = "";

                    if (contactDonor.Account.HasPaymentProcessorInfo() == false)
                    {
                        var stripeCustomer = _paymentService.CreateCustomer(null, contactDonor.DonorId + " Scanned Checks");

                        var stripeCustomerSource = _paymentService.AddSourceToCustomer(stripeCustomer.id, contactDonor.Account.Token);

                        donorAccountId = _mpDonorService.CreateDonorAccount(null,
                                                                            routing,
                                                                            account.Right(4),
                                                                            encryptedKey,
                                                                            contactDonor.DonorId,
                                                                            stripeCustomerSource.id,
                                                                            stripeCustomer.id).ToString();

                        contactDonor.Account = new MpDonorAccount
                        {
                            DonorAccountId     = int.Parse(donorAccountId),
                            ProcessorId        = stripeCustomer.id,
                            ProcessorAccountId = stripeCustomerSource.id
                        };
                    }
                    else
                    {
                        donorAccountId = contactDonor.Account.DonorAccountId.ToString();
                    }

                    //Always use the customer ID and source ID from the Donor Account, if it exists
                    var charge = _paymentService.ChargeCustomer(contactDonor.Account.ProcessorId, contactDonor.Account.ProcessorAccountId, check.Amount, contactDonor.DonorId, check.CheckNumber);

                    var fee = charge.BalanceTransaction != null ? charge.BalanceTransaction.Fee : null;

                    // Mark the check as exported now, so we don't double-charge a community member.
                    // If the CreateDonationAndDistributionRecord fails, we'll still consider it exported, but
                    // it will be in error, and will have to be manually resolved.
                    check.Exported = true;

                    var programId = batchDetails.ProgramId == null ? null : batchDetails.ProgramId + "";

                    var donationAndDistribution = new MpDonationAndDistributionRecord
                    {
                        DonationAmt           = check.Amount,
                        FeeAmt                = fee,
                        DonorId               = contactDonor.DonorId,
                        ProgramId             = programId,
                        ChargeId              = charge.Id,
                        PymtType              = "check",
                        ProcessorId           = contactDonor.Account.ProcessorId,
                        SetupDate             = check.CheckDate ?? (check.ScanDate ?? DateTime.Now),
                        RegisteredDonor       = contactDonor.RegisteredUser,
                        DonorAcctId           = donorAccountId,
                        CheckScannerBatchName = batchDetails.Name,
                        CheckNumber           = (check.CheckNumber ?? string.Empty).TrimStart(' ', '0').Right(MinistryPlatformCheckNumberMaxLength)
                    };

                    var donationId = _mpDonorService.CreateDonationAndDistributionRecord(donationAndDistribution, false);

                    check.DonationId = donationId;

                    _checkScannerDao.UpdateCheckStatus(check.Id, true);

                    batchDetails.Checks.Add(check);
                }
                catch (Exception e)
                {
                    check.Error         = e.ToString();
                    check.AccountNumber = _mpDonorService.DecryptCheckValue(check.AccountNumber);
                    check.RoutingNumber = _mpDonorService.DecryptCheckValue(check.RoutingNumber);
                    batchDetails.ErrorChecks.Add(check);
                    _checkScannerDao.UpdateCheckStatus(check.Id, check.Exported, check.Error);
                }
            }

            batchDetails.Status = BatchStatus.Exported;
            _checkScannerDao.UpdateBatchStatus(batchDetails.Name, batchDetails.Status);

            return(batchDetails);
        }