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;
        }
예제 #2
0
        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);
        }