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); }
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); }
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); }
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); }
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); } })); }
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); }
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); }
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); } })); }
/// <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); }
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; } }