private void UpdateFromGateway(IEnumerable <LcRest.UserPaymentPlan> list, LcLogger logger) { long reviewed = 0; long processed = 0; foreach (var userPlan in list) { try { // Query Braintree subscription var m = new LcPayment.Membership(); var subs = m.GetSubscription(userPlan.subscriptionID); reviewed++; if (subs == null) { // Problem: saved ID didn't found at Braintree, corrupted data var err = String.Format("Database subscriptionID '{0}' not found at Braintree, corrupted data." + " Please review user {1} subscription", userPlan.subscriptionID, userPlan.userID); LcMessaging.NotifyError("UserPaymentPlanSubscriptionUpdatesTask", "ScheduledTask", err); logger.Log(err); } else { // If status changed, update record if (userPlan.planStatus != subs.Status.ToString()) { userPlan.UpdatedAtGateway(subs); LcRest.UserPaymentPlan.Set(userPlan); // Update items count processed++; // Payments foreach (var transaction in subs.Transactions) { var payment = LcRest.UserFeePayment.FromSubscriptionTransaction(userPlan, transaction); LcRest.UserFeePayment.Set(payment); } } } } catch (Exception ex) { logger.LogEx("Pending and Past Due subscriptions", ex); } } logger.Log("Subscriptions updated from gateway: {0} from total reviewed {1}", processed, reviewed); ItemsReviewed += reviewed; ItemsProcessed += processed; }
public static UserPaymentPlan CreateSubscription( int userID, SubscriptionPlan plan, LcPayment.InputPaymentMethod paymentMethod) { // Prepare payment method (in the remote gateway), get its ID var paymentMethodToken = CollectPaymentMethod(paymentMethod, userID); // Prepare initial object var userPlan = new UserPaymentPlan() { userID = userID, paymentPlan = plan, subscriptionEndDate = null }; // Create subscription at gateway and set details // Wrapped in a try-catch to implement a transaction-like operation: // if something fail after succesfully create the Braintree subscription, like not being // able to save details on database, we need to 'rollback' the subscription, asking for removal // to Braintree string generatedSubscriptionId = null; var paymentPlan = new LcPayment.Membership(); try { if (LcPayment.TESTING_EMULATEBRAINTREE) { userPlan.subscriptionID = LcPayment.CreateFakeSubscriptionId(); userPlan.paymentPlanLastChangedDate = DateTimeOffset.Now; userPlan.nextPaymentDueDate = DateTimeOffset.Now.Add(new TimeSpan(365, 0, 0, 0)); userPlan.nextPaymentAmount = 99; userPlan.firstBillingDate = DateTimeOffset.Now; userPlan.planStatus = "ACTIVE"; userPlan.daysPastDue = 0; } else { // Start creating the subscription at the payment gateway var trialEndDate = GetUserTrialEndDate(userID); // Create the subscription at the payment gateway // It returns the subscription object with a correct ID on success, otherwise an exception is thrown var subscription = paymentPlan.CreateSubscription(plan, paymentMethodToken, trialEndDate); generatedSubscriptionId = subscription.Id; userPlan.subscriptionID = subscription.Id; userPlan.paymentPlanLastChangedDate = subscription.UpdatedAt.Value; userPlan.nextPaymentDueDate = subscription.NextBillingDate; userPlan.nextPaymentAmount = subscription.NextBillAmount; userPlan.firstBillingDate = subscription.FirstBillingDate.Value; userPlan.planStatus = subscription.Status.ToString(); userPlan.daysPastDue = subscription.DaysPastDue ?? 0; } // Fill payment method info var info = LcPayment.PaymentMethodInfo.Get(paymentMethodToken); userPlan.paymentExpiryDate = info.ExpirationDate; userPlan.paymentMethodToken = paymentMethodToken; userPlan.paymentMethod = info.Description; // Persist subscription on database Set(userPlan); } catch (Exception ex) { // Rollback if (generatedSubscriptionId != null) { // Rollback subscription at Payment Gateway paymentPlan.CancelSubscription(generatedSubscriptionId); } // The exception needs to be communicated anyway, so re-throw throw new Exception("[[[Failed subscription]]]", ex); } return(userPlan); }