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