Пример #1
0
        public void TestCreateRecurringGift()
        {
            const string stripeToken  = "tok_123";
            var          contactDonor = new MpContactDonor
            {
                Email = "*****@*****.**"
            };
            var contactDonorUpdated = new MpContactDonor
            {
                Email = "*****@*****.**"
            };
            var recurringGiftDto = new RecurringGiftDto
            {
                StripeTokenId = stripeToken
            };

            _donorService.Setup(mocked => mocked.GetContactDonorForAuthenticatedUser(_authType + " " + _authToken)).Returns(contactDonor);
            _donorService.Setup(mocked => mocked.CreateOrUpdateContactDonor(contactDonor, string.Empty, string.Empty, string.Empty, string.Empty, null, null)).Returns(contactDonorUpdated);
            _donorService.Setup(mocked => mocked.CreateRecurringGift(_authType + " " + _authToken, recurringGiftDto, contactDonorUpdated)).Returns(123);

            var response = _fixture.CreateRecurringGift(recurringGiftDto);

            _donorService.VerifyAll();
            Assert.IsNotNull(response);
            Assert.IsInstanceOf <OkNegotiatedContentResult <RecurringGiftDto> >(response);
            var dtoResponse = ((OkNegotiatedContentResult <RecurringGiftDto>)response).Content;

            Assert.IsNotNull(dtoResponse);
            Assert.AreSame(recurringGiftDto, dtoResponse);
            Assert.AreEqual(contactDonorUpdated.Email, recurringGiftDto.EmailAddress);
            Assert.AreEqual(123, recurringGiftDto.RecurringGiftId);
        }
Пример #2
0
        public void TestEditRecurringGiftStripeError()
        {
            var       authorizedUserToken = _authType + " " + _authToken;
            var       donor           = new MpContactDonor();
            var       editGift        = new RecurringGiftDto();
            const int recurringGiftId = 123;

            var stripeException = new PaymentProcessorException(HttpStatusCode.Forbidden,
                                                                "aux message",
                                                                "error type",
                                                                "message",
                                                                "code",
                                                                "decline code",
                                                                "param",
                                                                new ContentBlock());

            _donorService.Setup(mocked => mocked.GetContactDonorForAuthenticatedUser(authorizedUserToken)).Returns(donor);
            _donorService.Setup(mocked => mocked.EditRecurringGift(authorizedUserToken, editGift, donor)).Throws(stripeException);

            var response = _fixture.EditRecurringGift(recurringGiftId, editGift);

            _donorService.VerifyAll();
            Assert.AreEqual(recurringGiftId, editGift.RecurringGiftId);
            Assert.IsNotNull(response);
            Assert.IsInstanceOf <RestHttpActionResult <PaymentProcessorErrorResponse> >(response);
            var err = (RestHttpActionResult <PaymentProcessorErrorResponse>)response;

            Assert.AreEqual(HttpStatusCode.Forbidden, err.StatusCode);
        }
Пример #3
0
        public void TestCreateRecurringGiftStripeError()
        {
            const string stripeToken         = "tok_123";
            var          contactDonor        = new MpContactDonor();
            var          contactDonorUpdated = new MpContactDonor();
            var          recurringGiftDto    = new RecurringGiftDto
            {
                StripeTokenId = stripeToken
            };
            var stripeException = new PaymentProcessorException(HttpStatusCode.Forbidden,
                                                                "aux message",
                                                                "error type",
                                                                "message",
                                                                "code",
                                                                "decline code",
                                                                "param",
                                                                new ContentBlock());

            _donorService.Setup(mocked => mocked.GetContactDonorForAuthenticatedUser(_authType + " " + _authToken)).Returns(contactDonor);
            _donorService.Setup(mocked => mocked.CreateOrUpdateContactDonor(contactDonor, string.Empty, string.Empty, string.Empty, string.Empty, null, null)).Returns(contactDonorUpdated);
            _donorService.Setup(mocked => mocked.CreateRecurringGift(_authType + " " + _authToken, recurringGiftDto, contactDonorUpdated)).Throws(stripeException);

            var response = _fixture.CreateRecurringGift(recurringGiftDto);

            _donorService.VerifyAll();
            Assert.IsNotNull(response);
            Assert.IsInstanceOf <RestHttpActionResult <PaymentProcessorErrorResponse> >(response);
            var err = (RestHttpActionResult <PaymentProcessorErrorResponse>)response;

            Assert.AreEqual(HttpStatusCode.Forbidden, err.StatusCode);
        }
Пример #4
0
        public StripePlan CreatePlan(RecurringGiftDto recurringGiftDto, MpContactDonor mpContactDonor)
        {
            var request = new RestRequest("plans", Method.POST);

            var interval = EnumMemberSerializationUtils.ToEnumString(recurringGiftDto.PlanInterval);

            request.AddParameter("amount", (int)(recurringGiftDto.PlanAmount * Constants.StripeDecimalConversionValue));
            request.AddParameter("interval", interval);
            request.AddParameter("name", string.Format("Donor ID #{0} {1}ly", mpContactDonor.DonorId, interval));
            request.AddParameter("currency", "usd");
            request.AddParameter("id", mpContactDonor.DonorId + " " + DateTime.Now);

            var response = _stripeRestClient.Execute <StripePlan>(request);

            CheckStripeResponse("Invalid plan creation request", response);

            return(response.Data);
        }
Пример #5
0
        public IHttpActionResult CreateRecurringGift([FromBody] RecurringGiftDto recurringGiftDto, [FromUri(Name = "impersonateDonorId")] int?impersonateDonorId = null)
        {
            return(Authorized(token =>
            {
                var impersonateUserId = impersonateDonorId == null ? string.Empty : _mpDonorService.GetEmailViaDonorId(impersonateDonorId.Value).Email;

                try
                {
                    var contactDonor = (impersonateDonorId != null)
                        ? _impersonationService.WithImpersonation(token,
                                                                  impersonateUserId,
                                                                  () =>
                                                                  _donorService.GetContactDonorForAuthenticatedUser(token))
                        : _donorService.GetContactDonorForAuthenticatedUser(token);
                    var donor = _donorService.CreateOrUpdateContactDonor(contactDonor, string.Empty, string.Empty, string.Empty, string.Empty);
                    var recurringGift = !string.IsNullOrWhiteSpace(impersonateUserId)
                        ? _impersonationService.WithImpersonation(token,
                                                                  impersonateUserId,
                                                                  () =>
                                                                  _donorService.CreateRecurringGift(token, recurringGiftDto, donor))
                        : _donorService.CreateRecurringGift(token, recurringGiftDto, donor);

                    recurringGiftDto.EmailAddress = donor.Email;
                    recurringGiftDto.RecurringGiftId = recurringGift;

                    _analyticsService.Track(donor.ContactId.ToString(), "PaymentSucceededServerSide", new EventProperties()
                    {
                        { "Url", recurringGiftDto.SourceUrl }, { "FundingMethod", recurringGiftDto.Source }, { "Email", "" }, { "CheckoutType", "Registered" }, { "Amount", recurringGiftDto.PlanAmount }
                    });

                    return Ok(recurringGiftDto);
                }
                catch (PaymentProcessorException stripeException)
                {
                    return (stripeException.GetStripeResult());
                }
                catch (ApplicationException applicationException)
                {
                    var apiError = new ApiErrorDto("Error calling Ministry Platform " + applicationException.Message, applicationException);
                    throw new HttpResponseException(apiError.HttpResponseMessage);
                }
            }));
        }
Пример #6
0
        public void TestEditRecurringGiftMinistryPlatformException()
        {
            var       authorizedUserToken = _authType + " " + _authToken;
            var       donor           = new MpContactDonor();
            var       editGift        = new RecurringGiftDto();
            const int recurringGiftId = 123;

            _donorService.Setup(mocked => mocked.GetContactDonorForAuthenticatedUser(authorizedUserToken)).Returns(donor);
            _donorService.Setup(mocked => mocked.EditRecurringGift(authorizedUserToken, editGift, donor)).Throws <ApplicationException>();

            try
            {
                _fixture.EditRecurringGift(recurringGiftId, editGift);
                Assert.Fail("expected exception was not thrown");
            }
            catch (HttpResponseException)
            {
                // expected
            }
            _donorService.VerifyAll();

            Assert.AreEqual(recurringGiftId, editGift.RecurringGiftId);
        }
Пример #7
0
        public void TestEditRecurringGift()
        {
            var       authorizedUserToken = _authType + " " + _authToken;
            var       donor           = new MpContactDonor();
            var       editGift        = new RecurringGiftDto();
            var       newGift         = new RecurringGiftDto();
            const int recurringGiftId = 123;

            _donorService.Setup(mocked => mocked.GetContactDonorForAuthenticatedUser(authorizedUserToken)).Returns(donor);
            _donorService.Setup(mocked => mocked.EditRecurringGift(authorizedUserToken, editGift, donor)).Returns(newGift);

            var response = _fixture.EditRecurringGift(recurringGiftId, editGift);

            _donorService.VerifyAll();

            Assert.AreEqual(recurringGiftId, editGift.RecurringGiftId);
            Assert.IsNotNull(response);
            Assert.IsInstanceOf <OkNegotiatedContentResult <RecurringGiftDto> >(response);
            var dtoResponse = ((OkNegotiatedContentResult <RecurringGiftDto>)response).Content;

            Assert.IsNotNull(dtoResponse);
            Assert.AreSame(newGift, dtoResponse);
        }
Пример #8
0
        public IHttpActionResult EditRecurringGift([FromUri] int recurringGiftId, [FromBody] RecurringGiftDto editGift, [FromUri(Name = "impersonateDonorId")] int?impersonateDonorId = null)
        {
            editGift.RecurringGiftId = recurringGiftId;

            return(Authorized(token =>
            {
                var impersonateUserId = impersonateDonorId == null ? string.Empty : _mpDonorService.GetEmailViaDonorId(impersonateDonorId.Value).Email;

                try
                {
                    var donor = (impersonateDonorId != null)
                        ? _impersonationService.WithImpersonation(token,
                                                                  impersonateUserId,
                                                                  () =>
                                                                  _donorService.GetContactDonorForAuthenticatedUser(token))
                        : _donorService.GetContactDonorForAuthenticatedUser(token);

                    var recurringGift = !string.IsNullOrWhiteSpace(impersonateUserId)
                        ? _impersonationService.WithImpersonation(token,
                                                                  impersonateUserId,
                                                                  () =>
                                                                  _donorService.EditRecurringGift(token, editGift, donor))
                        : _donorService.EditRecurringGift(token, editGift, donor);

                    return Ok(recurringGift);
                }
                catch (PaymentProcessorException stripeException)
                {
                    return (stripeException.GetStripeResult());
                }
                catch (ApplicationException applicationException)
                {
                    var apiError = new ApiErrorDto("Error calling Ministry Platform " + applicationException.Message, applicationException);
                    throw new HttpResponseException(apiError.HttpResponseMessage);
                }
            }));
        }
Пример #9
0
        /// <summary>
        /// Edit an existing recurring gift.  This will cancel (end-date) an existing RecurringGift and then create a new one
        /// if the Program, Amount, Frequency, Day of Week, or Day of Month are changed.  This will simply edit the existing gift
        /// if only the payment method (credit card, bank account) is changed.
        /// </summary>
        /// <param name="authorizedUserToken">An OAuth token for the user who is logged in to cr.net/MP</param>
        /// <param name="editGift">The edited values for the Recurring Gift</param>
        /// <param name="donor>The donor performing the edits</param>
        /// <returns>A RecurringGiftDto, populated with any new/updated values after any edits</returns>
        public RecurringGiftDto EditRecurringGift(string authorizedUserToken, RecurringGiftDto editGift, MpContactDonor donor)
        {
            var existingGift = _mpDonorService.GetRecurringGiftById(authorizedUserToken, editGift.RecurringGiftId);

            // Assuming payment info is changed if a token is given.
            var changedPayment = !string.IsNullOrWhiteSpace(editGift.StripeTokenId);

            var changedAmount     = (int)(editGift.PlanAmount * Constants.StripeDecimalConversionValue) != existingGift.Amount;
            var changedProgram    = !editGift.Program.Equals(existingGift.ProgramId);
            var changedFrequency  = !editGift.PlanInterval.Equals(existingGift.Frequency == RecurringGiftFrequencyWeekly ? PlanInterval.Weekly : PlanInterval.Monthly);
            var changedDayOfWeek  = changedFrequency || (editGift.PlanInterval == PlanInterval.Weekly && (int)editGift.StartDate.DayOfWeek != existingGift.DayOfWeek);
            var changedDayOfMonth = changedFrequency || (editGift.PlanInterval == PlanInterval.Monthly && editGift.StartDate.Day != existingGift.DayOfMonth);
            var changedStartDate  = editGift.StartDate.Date != existingGift.StartDate.GetValueOrDefault().Date;

            var needsUpdatedStripeSubscription = changedAmount && !(changedFrequency || changedDayOfWeek || changedDayOfMonth || changedStartDate);
            var needsNewStripePlan             = changedAmount || changedFrequency || changedDayOfWeek || changedDayOfMonth || changedStartDate;
            var needsNewMpRecurringGift        = changedAmount || changedProgram || needsNewStripePlan;

            var recurringGiftId = existingGift.RecurringGiftId.GetValueOrDefault(-1);

            int donorAccountId;

            if (changedPayment)
            {
                // If the payment method changed, we need to create a new Stripe Source.
                var source = _paymentService.UpdateCustomerSource(existingGift.StripeCustomerId, editGift.StripeTokenId);

                donorAccountId = _mpDonorService.CreateDonorAccount(source.brand,
                                                                    DonorRoutingNumberDefault,
                                                                    string.IsNullOrWhiteSpace(source.bank_last4) ? source.last4 : source.bank_last4,
                                                                    null, //Encrypted account
                                                                    existingGift.DonorId,
                                                                    source.id,
                                                                    existingGift.StripeCustomerId);

                // If we are not going to create a new Recurring Gift, then we'll update the existing
                // gift with the new donor account
                if (!needsNewMpRecurringGift)
                {
                    _mpDonorService.UpdateRecurringGiftDonorAccount(authorizedUserToken, recurringGiftId, donorAccountId);
                }
            }
            else
            {
                // If the payment method is not changed, set the donorAccountId with the existing ID so we can use it later
                donorAccountId = existingGift.DonorAccountId.GetValueOrDefault();
            }

            // Initialize a StripeSubscription, as we need the ID later on
            var stripeSubscription = new StripeSubscription {
                Id = existingGift.SubscriptionId
            };

            if (needsNewMpRecurringGift)
            {
                if (needsNewStripePlan)
                {
                    // Create the new Stripe Plan
                    var plan = _paymentService.CreatePlan(editGift, donor);
                    StripeSubscription oldSubscription;
                    if (needsUpdatedStripeSubscription)
                    {
                        // If we just changed the amount, we just need to update the Subscription to point to the new plan
                        oldSubscription    = _paymentService.GetSubscription(existingGift.StripeCustomerId, stripeSubscription.Id);
                        stripeSubscription = _paymentService.UpdateSubscriptionPlan(existingGift.StripeCustomerId,
                                                                                    stripeSubscription.Id,
                                                                                    plan.Id,
                                                                                    oldSubscription.TrialEnd);
                    }
                    else
                    {
                        // Otherwise, we need to cancel the old Subscription and create a new one
                        oldSubscription    = _paymentService.CancelSubscription(existingGift.StripeCustomerId, stripeSubscription.Id);
                        stripeSubscription = _paymentService.CreateSubscription(plan.Id, existingGift.StripeCustomerId, editGift.StartDate);
                    }

                    // In either case, we created a new Stripe Plan above, so cancel the old one
                    _paymentService.CancelPlan(oldSubscription.Plan.Id);
                }

                // Cancel the old recurring gift, and create a new one
                _mpDonorService.CancelRecurringGift(authorizedUserToken, recurringGiftId);
                var contact      = _mpContactService.GetContactById(donor.ContactId);
                var congregation = contact.Congregation_ID ?? 5;

                recurringGiftId = _mpDonorService.CreateRecurringGiftRecord(authorizedUserToken,
                                                                            donor.DonorId,
                                                                            donorAccountId,
                                                                            EnumMemberSerializationUtils.ToEnumString(editGift.PlanInterval),
                                                                            editGift.PlanAmount,
                                                                            editGift.StartDate,
                                                                            editGift.Program,
                                                                            stripeSubscription.Id,
                                                                            congregation);
            }

            // Get the new/updated recurring gift so we can return a DTO with all the new values
            var newGift = _mpDonorService.GetRecurringGiftById(authorizedUserToken, recurringGiftId);

            var newRecurringGift = new RecurringGiftDto
            {
                RecurringGiftId = newGift.RecurringGiftId.GetValueOrDefault(),
                StartDate       = newGift.StartDate.GetValueOrDefault(),
                PlanAmount      = newGift.Amount,
                PlanInterval    = newGift.Frequency == RecurringGiftFrequencyWeekly ? PlanInterval.Weekly : PlanInterval.Monthly,
                Program         = newGift.ProgramId,
                DonorID         = newGift.DonorId,
                EmailAddress    = donor.Email,
                SubscriptionID  = stripeSubscription.Id,
            };

            SendRecurringGiftConfirmationEmail(authorizedUserToken, _recurringGiftUpdateEmailTemplateId, newGift);

            return(newRecurringGift);
        }
Пример #10
0
        public int CreateRecurringGift(string authorizedUserToken, RecurringGiftDto recurringGiftDto, MpContactDonor mpContactDonor)
        {
            StripeCustomer     customer           = null;
            StripePlan         plan               = null;
            StripeSubscription stripeSubscription = null;
            var donorAccountId = -1;
            var recurGiftId    = -1;

            try
            {
                customer = _paymentService.CreateCustomer(recurringGiftDto.StripeTokenId, string.Format("{0}, Recurring Gift Subscription", mpContactDonor.DonorId));

                var source = customer.sources.data.Find(s => s.id == customer.default_source);

                donorAccountId = _mpDonorService.CreateDonorAccount(source.brand,
                                                                    DonorRoutingNumberDefault,
                                                                    string.IsNullOrWhiteSpace(source.bank_last4) ? source.last4 : source.bank_last4,
                                                                    null,
                                                                    mpContactDonor.DonorId,
                                                                    source.id,
                                                                    customer.id);

                plan = _paymentService.CreatePlan(recurringGiftDto, mpContactDonor);

                stripeSubscription = _paymentService.CreateSubscription(plan.Id, customer.id, recurringGiftDto.StartDate);

                var contact      = _mpContactService.GetContactById(mpContactDonor.ContactId);
                var congregation = contact.Congregation_ID ?? _notSiteSpecificCongregation;

                recurGiftId = _mpDonorService.CreateRecurringGiftRecord(authorizedUserToken,
                                                                        mpContactDonor.DonorId,
                                                                        donorAccountId,
                                                                        EnumMemberSerializationUtils.ToEnumString(recurringGiftDto.PlanInterval),
                                                                        recurringGiftDto.PlanAmount,
                                                                        recurringGiftDto.StartDate,
                                                                        recurringGiftDto.Program,
                                                                        stripeSubscription.Id,
                                                                        congregation,
                                                                        recurringGiftDto.SourceUrl,
                                                                        recurringGiftDto.PredefinedAmount);

                SendRecurringGiftConfirmationEmail(authorizedUserToken, _recurringGiftSetupEmailTemplateId, null, recurGiftId);

                return(recurGiftId);
            }
            catch (Exception e)
            {
                // "Rollback" any updates
                _logger.Warn(string.Format("Error setting up recurring gift for donor {0}", mpContactDonor.DonorId), e);
                if (stripeSubscription != null)
                {
                    _logger.Debug(string.Format("Deleting Stripe Subscription {0} for donor {1}", stripeSubscription.Id, mpContactDonor.DonorId));
                    try
                    {
                        _paymentService.CancelSubscription(customer.id, stripeSubscription.Id);
                    }
                    catch (Exception ex)
                    {
                        _logger.Warn(string.Format("Error deleting Stripe Subscription {0} for donor {1}", stripeSubscription.Id, mpContactDonor.DonorId), ex);
                    }
                }

                if (plan != null)
                {
                    _logger.Debug(string.Format("Deleting Stripe Plan {0} for donor {1}", plan.Id, mpContactDonor.DonorId));
                    try
                    {
                        _paymentService.CancelPlan(plan.Id);
                    }
                    catch (Exception ex)
                    {
                        _logger.Warn(string.Format("Error deleting Stripe Plan {0} for donor {1}", plan.Id, mpContactDonor.DonorId), ex);
                    }
                }

                if (customer != null)
                {
                    _logger.Debug(string.Format("Deleting Stripe Customer {0} for donor {1}", customer.id, mpContactDonor.DonorId));
                    try
                    {
                        _paymentService.DeleteCustomer(customer.id);
                    }
                    catch (Exception ex)
                    {
                        _logger.Warn(string.Format("Error deleting Stripe Customer {0} for donor {1}", customer.id, mpContactDonor.DonorId), ex);
                    }
                }

                if (donorAccountId != -1)
                {
                    _logger.Debug(string.Format("Deleting Donor Account {0} for donor {1}", donorAccountId, mpContactDonor.DonorId));
                    try
                    {
                        _mpDonorService.DeleteDonorAccount(authorizedUserToken, donorAccountId);
                    }
                    catch (Exception ex)
                    {
                        _logger.Warn(string.Format("Error deleting Donor Account {0} for donor {1}", donorAccountId, mpContactDonor.DonorId), ex);
                    }
                }

                if (recurGiftId != -1)
                {
                    _logger.Debug(string.Format("Deleting Recurring Gift {0} for donor {1}", recurGiftId, mpContactDonor.DonorId));
                    try
                    {
                        _mpDonorService.CancelRecurringGift(authorizedUserToken, recurGiftId);
                    }
                    catch (Exception ex)
                    {
                        _logger.Warn(string.Format("Error deleting Recurring Gift {0} for donor {1}", recurGiftId, mpContactDonor.DonorId), ex);
                    }
                }

                throw;
            }
        }