예제 #1
0
 /* Notes: serialized values of SubscriptionStatus
  * Braintree.SubscriptionStatus.STATUSES.Select(s => s.ToString());
  *  string "Active"
  *  string "Canceled"
  *  string "Expired"
  *  string "Past Due"
  *  string "Pending"
  */
 /// <summary>
 /// Run membership requirements checks and returns
 /// the OwnerStatus that is expected for the user based on that
 /// (but is not saved and previous status is not checked).
 /// </summary>
 /// <param name="userID"></param>
 /// <returns>Status based on requirements</returns>
 public static LcEnum.OwnerStatus GetExpectedOwnerStatus(int userID)
 {
     // Check all requirements
     if (UserJobTitle.MeetsOwnershipRequirement(userID) &&
         OwnerAcknowledgment.MeetsOwnsershipRequirement(userID) &&
         UserPaymentPlan.MeetsOwnsershipRequirement(userID))
     {
         // It's OK
         return(LcEnum.OwnerStatus.active);
     }
     else
     {
         // It failed
         var status = UserPaymentPlan.GetLastPaymentPlanStatus(userID);
         if (status == Braintree.SubscriptionStatus.CANCELED)
         {
             return(LcEnum.OwnerStatus.cancelled);
         }
         else if (status == Braintree.SubscriptionStatus.EXPIRED)
         {
             return(LcEnum.OwnerStatus.suspended);
         }
         else
         {
             return(LcEnum.OwnerStatus.inactive);
         }
     }
 }
예제 #2
0
        /// <summary>
        /// Create an instance for a plan subscription and
        /// a payment transaction.
        /// If transaction exists on database, it gets the record updating the transaction status.
        /// </summary>
        /// <param name="userPlan"></param>
        /// <param name="transaction"></param>
        /// <returns></returns>
        public static UserFeePayment FromSubscriptionTransaction(UserPaymentPlan userPlan, Braintree.Transaction transaction)
        {
            var payment = GetBySubscriptionTransaction(userPlan.userID, userPlan.subscriptionID, transaction.Id);

            if (payment == null)
            {
                // New one
                payment = new UserFeePayment
                {
                    userID         = userPlan.userID,
                    subscriptionID = userPlan.subscriptionID,
                    paymentAmount  = transaction.Amount ?? 0,
                    paymentDate    = transaction.CreatedAt ?? DateTime.Now,
                    paymentMethod  = userPlan.paymentMethod,
                    //paymentMethod = LcPayment.PaymentMethodInfo.Get(transaction.CreditCard.Token).Description,
                    paymentPlan          = transaction.PlanId,
                    paymentStatus        = transaction.Status.ToString(),
                    paymentTransactionID = transaction.Id
                };
            }
            else
            {
                // Update status
                payment.paymentStatus = transaction.Status.ToString();
            }
            return(payment);
        }
예제 #3
0
        public static void Set(UserPaymentPlan data, LcDatabase sharedDb = null)
        {
            using (var db = new LcDatabase(sharedDb))
            {
                db.Execute(sqlSet,
                           data.userPaymentPlanID,
                           data.userID,
                           data.subscriptionID,
                           data.paymentPlan.ToString(),
                           data.paymentMethod,
                           data.paymentPlanLastChangedDate,
                           data.nextPaymentDueDate,
                           data.nextPaymentAmount,
                           data.firstBillingDate,
                           data.subscriptionEndDate,
                           data.paymentMethodToken,
                           data.paymentExpiryDate,
                           data.planStatus,
                           data.daysPastDue
                           );

                try
                {
                    // Set OwnerStatus
                    if (IsPartnershipPlan(data.paymentPlan))
                    {
                        var ow = new Owner();
                        ow.userID   = data.userID;
                        ow.statusID = (int)OwnerStatus.notYetAnOwner;
                        Owner.Set(ow);
                    }
                    else
                    {
                        // Run Membership Checks to enable/disable member (OwnerStatus update)
                        UserProfile.CheckAndSaveOwnerStatus(data.userID);
                    }
                }
                catch (Exception ex)
                {
                    // An error checking status must NOT prevent us from saving/creating
                    // the payment-plan, but we must notify staff so we can take manual action
                    // to fix the error and run the check again for this user
                    try
                    {
                        LcLogger.LogAspnetError(ex);
                        LcMessaging.NotifyError("UserPaymentPlan.Set->UserProfile.CheckAndSaveOwnerStatus::userID=" + data.userID,
                                                System.Web.HttpContext.Current.Request.RawUrl,
                                                ex.ToString());
                    }
                    catch
                    {
                        // Prevent cancel paymentplan creation/update because of email or log failing. Really strange
                        // and webhook-scheduleTask for subscriptions would attempt again this.
                    }
                }
            }
        }
예제 #4
0
 public static void Set(UserPaymentPlan data)
 {
     using (var db = new LcDatabase())
     {
         db.Execute(sqlSet,
                    data.userID,
                    data.paymentPlan,
                    data.paymentMethod,
                    data.paymentPlanLastChangedDate,
                    data.nextPaymentDueDate,
                    data.nextPaymentAmount,
                    data.lastPaymentDate,
                    data.lastPaymentAmount,
                    data.totalPastDueAmount
                    );
     }
 }
예제 #5
0
        /// <summary>
        /// Creates a special subscription that has not a payment with the user
        /// but with a Partner, and as part of it the user (that related with the Partner)
        /// gets free access for a Loconomics plan.
        /// </summary>
        /// <param name="userID"></param>
        /// <param name="plan"></param>
        /// <param name="paymentMethod"></param>
        /// <returns></returns>
        public static UserPaymentPlan CreatePartnershipSubscription(
            int userID,
            SubscriptionPlan plan,
            LcDatabase db)
        {
            // Validate plan
            if (!IsPartnershipPlan(plan))
            {
                throw new ConstraintException("[[[Invalid subscription plan for a partnership]]]");
            }
            // Setup of the plan
            var durationDays = 0;

            switch (plan)
            {
            case SubscriptionPlan.CccPlan:
                durationDays = CccPartnershipSubscriptionDurationDays;
                break;
            }
            // Prepare object
            var userPlan = new UserPaymentPlan()
            {
                userID                     = userID,
                paymentPlan                = plan,
                subscriptionEndDate        = null,
                subscriptionID             = "",
                paymentPlanLastChangedDate = DateTimeOffset.Now,
                nextPaymentDueDate         = DateTimeOffset.Now.Add(new TimeSpan(durationDays, 0, 0, 0)),
                nextPaymentAmount          = null,
                firstBillingDate           = DateTimeOffset.Now,
                planStatus                 = "ACTIVE",
                daysPastDue                = 0,
                paymentExpiryDate          = null,
                paymentMethodToken         = "",
                paymentMethod              = "",
            };

            // Persist subscription on database
            Set(userPlan, db);
            return(userPlan);
        }
예제 #6
0
 public static void Set(UserPaymentPlan data)
 {
     using (var db = new LcDatabase())
     {
         db.Execute(sqlSet,
                    data.userPaymentPlanID,
                    data.userID,
                    data.subscriptionID,
                    data.paymentPlan.ToString(),
                    data.paymentMethod,
                    data.paymentPlanLastChangedDate,
                    data.nextPaymentDueDate,
                    data.nextPaymentAmount,
                    data.firstBillingDate,
                    data.subscriptionEndDate,
                    data.paymentMethodToken,
                    data.paymentExpiryDate,
                    data.planStatus,
                    data.daysPastDue
                    );
     }
 }
예제 #7
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);
        }