Пример #1
0
        /// <summary>
        /// Creates or updates an MP Donor (and potentially creates a Contact) appropriately, based on the following logic:
        /// 1) If the given MpContactDonor is null, or if it does not represent an existing Contact,
        ///    create a Contact and Donor in MP, and create Customer in the payment processor system.  This
        ///    Contact and Donor will be considered a Guest Giver, unrelated to any registered User.
        ///
        /// 2) If the given MpContactDonor is an existing mpContact, but does not have a payment processor customer,
        ///    create a Customer in the payment processor system, then either create a new Donor with the
        ///    payment processor Customer ID, or update the existing Donor (if any) with the id.
        ///
        /// 3) If the given MpContactDonor is an existing mpContact, and an existing Donor with a Customer ID in the
        ///    payment processor system, simply return the given MpContactDonor.  This is a fallback, put in place
        ///    to take some of the decision logic out of the frontend on whether a new Donor needs to be created or not,
        ///    whether a Customer needs to be created at the payment processor, etc.
        /// </summary>
        /// <param name="mpContactDonor">An existing MpContactDonor, looked up from either GetDonorForEmail or GetDonorForAuthenticatedUser.  This may be null, indicating there is no existing mpContact or donor.</param>
        /// <param name="encryptedKey"> The encrypted routing and account number</param>
        /// <param name="dto"></param>
        /// <param name="lastName"></param>
        /// <param name="emailAddress">An email address to use when creating a Contact (#1 above).</param>
        /// <param name="paymentProcessorToken">The one-time-use token given by the payment processor - if not set, a donor will still be potentially created or updated, but will not be setup in Stripe.</param>
        /// <param name="setupDate">The date when the Donor is marked as setup, defaults to today's date.</param>
        /// <param name="firstName"></param>
        /// <returns></returns>
        public MpContactDonor CreateOrUpdateContactDonor(MpContactDonor mpContactDonor, string encryptedKey, string firstName, string lastName, string emailAddress, string paymentProcessorToken = null, DateTime?setupDate = null)
        {
            setupDate = setupDate ?? DateTime.Now;

            var contactDonorResponse = new MpContactDonor();

            if (mpContactDonor == null || !mpContactDonor.ExistingContact)
            {
                var statementMethod    = _statementMethodNone;
                var statementFrequency = _statementFrequencyNever;
                if (mpContactDonor != null && mpContactDonor.HasDetails)
                {
                    contactDonorResponse.ContactId = _mpContactService.CreateContactForNewDonor(mpContactDonor);
                    statementMethod    = _statementMethodPostalMail;
                    statementFrequency = _statementFrequencyQuarterly;
                }
                else
                {
                    var displayName = _guestGiverDisplayName;
                    if (!string.IsNullOrEmpty(firstName) && !string.IsNullOrEmpty(lastName))
                    {
                        displayName = firstName;
                    }
                    contactDonorResponse.ContactId = _mpContactService.CreateContactForGuestGiver(emailAddress, displayName, firstName, lastName);
                }

                var donorAccount = mpContactDonor != null ? mpContactDonor.Account : null;
                if (!string.IsNullOrWhiteSpace(paymentProcessorToken))
                {
                    var stripeCustomer = _paymentService.CreateCustomer(paymentProcessorToken);

                    if (donorAccount != null)
                    {
                        donorAccount.ProcessorAccountId = stripeCustomer.sources.data[0].id;
                    }

                    contactDonorResponse.ProcessorId = stripeCustomer.id;
                }

                contactDonorResponse.DonorId = _mpDonorService.CreateDonorRecord(contactDonorResponse.ContactId, contactDonorResponse.ProcessorId, setupDate.Value,
                                                                                 statementFrequency, _statementTypeIndividual, statementMethod, donorAccount);
                contactDonorResponse.Email = emailAddress;

                _paymentService.UpdateCustomerDescription(contactDonorResponse.ProcessorId, contactDonorResponse.DonorId);

                if (donorAccount != null)
                {
                    _mpDonorService.CreateDonorAccount(null /* gift type, not needed here */,
                                                       donorAccount.RoutingNumber,
                                                       donorAccount.AccountNumber.Right(4),
                                                       donorAccount.EncryptedAccount,
                                                       contactDonorResponse.DonorId,
                                                       donorAccount.ProcessorAccountId,
                                                       contactDonorResponse.ProcessorId);
                }
            }
            else if (!mpContactDonor.HasPaymentProcessorRecord)
            {
                contactDonorResponse.ContactId = mpContactDonor.ContactId;
                if (!string.IsNullOrWhiteSpace(paymentProcessorToken))
                {
                    var stripeCustomer = _paymentService.CreateCustomer(paymentProcessorToken);
                    contactDonorResponse.ProcessorId = stripeCustomer.id;
                    if (mpContactDonor.HasAccount)
                    {
                        mpContactDonor.Account.ProcessorAccountId = stripeCustomer.sources.data[0].id;
                    }
                }

                if (mpContactDonor.ExistingDonor)
                {
                    contactDonorResponse.DonorId = _mpDonorService.UpdatePaymentProcessorCustomerId(mpContactDonor.DonorId, contactDonorResponse.ProcessorId);
                    contactDonorResponse.Email   = mpContactDonor.Email;
                }
                else
                {
                    if (mpContactDonor.RegisteredUser)
                    {
                        contactDonorResponse.DonorId = _mpDonorService.CreateDonorRecord(mpContactDonor.ContactId, contactDonorResponse.ProcessorId, setupDate.Value);
                        var contact = _mpDonorService.GetEmailViaDonorId(contactDonorResponse.DonorId);
                        contactDonorResponse.Email = contact.Email;
                    }
                    else
                    {
                        contactDonorResponse.DonorId = _mpDonorService.CreateDonorRecord(mpContactDonor.ContactId, contactDonorResponse.ProcessorId, setupDate.Value,
                                                                                         _statementFrequencyNever, _statementTypeIndividual, _statementMethodNone);
                        contactDonorResponse.Email = mpContactDonor.Email;
                    }
                }

                if (mpContactDonor.HasAccount)
                {
                    _mpDonorService.CreateDonorAccount(null /* gift type, not needed here */,
                                                       mpContactDonor.Account.RoutingNumber,
                                                       mpContactDonor.Account.AccountNumber.Right(4),
                                                       mpContactDonor.Account.EncryptedAccount,
                                                       mpContactDonor.DonorId,
                                                       mpContactDonor.Account.ProcessorAccountId,
                                                       mpContactDonor.ProcessorId);
                }

                if (contactDonorResponse.HasPaymentProcessorRecord)
                {
                    _paymentService.UpdateCustomerDescription(contactDonorResponse.ProcessorId, contactDonorResponse.DonorId);
                }
                contactDonorResponse.RegisteredUser = mpContactDonor.RegisteredUser;
            }
            else if (mpContactDonor.HasAccount && mpContactDonor.Account.HasToken && AccountType.Checking == mpContactDonor.Account.Type)
            {
                var source = _paymentService.AddSourceToCustomer(mpContactDonor.ProcessorId, mpContactDonor.Account.Token);
                _mpDonorService.CreateDonorAccount(null /* gift type, not needed here */,
                                                   mpContactDonor.Account.RoutingNumber,
                                                   mpContactDonor.Account.AccountNumber.Right(4),
                                                   mpContactDonor.Account.EncryptedAccount,
                                                   mpContactDonor.DonorId,
                                                   source.id,
                                                   mpContactDonor.ProcessorId);

                contactDonorResponse = mpContactDonor;
                contactDonorResponse.Account.ProcessorAccountId = source.id;
                contactDonorResponse.Account.ProcessorId        = mpContactDonor.ProcessorId;
            }
            else
            {
                contactDonorResponse = mpContactDonor;
            }

            return(contactDonorResponse);
        }