/// <summary> /// Creates payment history entry. /// </summary> /// <param name="userId">User Id.</param> /// <param name="options">Payment options.</param> /// <param name="amount">Amount.</param> /// <param name="chargedTo">Account charged to.</param> /// <param name="transactionId">Transaction Id.</param> /// <param name="autoUpdateSubscription">Value indicating whether to automatically update user subscription.</param> public void CreatePaymentHistoryEntry( int userId, PaymentOptions options, int amount, string chargedTo, string transactionId, bool autoUpdateSubscription) { User u = null; if (autoUpdateSubscription) { using (var repo = Resolver.Resolve <IUserRepository>()) { u = repo.Select(userId); if (u != null) { if (u.Subscription == null) { u.Subscription = new UserSubscription(); } u.Subscription.Renewed = DateTime.UtcNow; u.Subscription.RenewedTo = options.Subscription; u.Subscription.RenewedToDuration = options.Duration; repo.Update(u); } } } var ret = new PaymentHistoryEntry() { UserId = userId, Date = DateTime.UtcNow, SubscriptionType = options.Subscription, Duration = options.Duration, Amount = amount / 100, // In dollars, not in cents ChargedTo = chargedTo, TransactionId = transactionId }; _payments.Update(ret); // Eventual consistency, you know... System.Threading.Thread.Sleep(500); }
/// <summary> /// Returns charge amount for a given subscription type. /// </summary> /// <param name="options">Payment options.</param> /// <returns>Charge amount (in cents).</returns> public int GetChargeAmount(PaymentOptions options) { int ret = 0; switch (options.Subscription) { case SubscriptionType.Pro: ret = options.Duration == SubscriptionDuration.OneMonth ? 300 : 2700; break; case SubscriptionType.Agency: ret = options.Duration == SubscriptionDuration.OneMonth ? 900 : 8100; break; default: ret = 0; break; } return(ret); }
/// <summary> /// Gets or sets value indicating whether the given user has valid payment for a given subscription. /// </summary> /// <param name="userId">User Id.</param> /// <param name="options">Payment options.</param> /// <returns>Value indicating whether the given user has valid payment for a given subscription.</returns> public bool HasValidPayment(int userId, PaymentOptions options) { bool ret = false; PaymentHistoryEntry firstEntry = null; var history = this.GetPaymentHistory(userId); if (history.Any()) { firstEntry = history.First(); if (options.Subscription == SubscriptionType.Pro) { ret = true; } else if (options.Subscription == SubscriptionType.Agency) { ret = firstEntry.SubscriptionType == SubscriptionType.Agency; } } return(ret); }
/// <summary> /// Tries to create a charge. /// </summary> /// <param name="userId">User Id.</param> /// <param name="options">Payment options.</param> /// <param name="token">Card token.</param> /// <param name="description">Charge description.</param> /// <exception cref="Ifly.Payments.ChargeException">Occurs when charge is failed.</exception> public void TryCreateCharge(int userId, PaymentOptions options, string token, string description) { User u = null; int amount = 0; Stripe.StripeCharge charge = null; ChargeException.ChargeFailureReason?reason = null; if (userId > 0 && !string.IsNullOrEmpty(token) && options.Subscription != SubscriptionType.Basic) { using (var repo = Resolver.Resolve <IUserRepository>()) { u = repo.Select(userId); if (u != null) { try { amount = this.GetChargeAmount(options); if (amount > 0) { charge = new Stripe.StripeChargeService().Create(new Stripe.StripeChargeCreateOptions() { Amount = amount, Currency = "usd", Card = token, Description = description.IndexOf("{0}") >= 0 ? string.Format(description, (int)(amount / 100)) : description }); if (!charge.Paid.HasValue || !charge.Paid.Value) { OnChargeException(new InvalidOperationException("Charge failed (response from Stripe)."), userId, options.Subscription, token, u, charge); } else { if (u.Subscription == null) { u.Subscription = new UserSubscription(); } u.Subscription.Renewed = DateTime.UtcNow; u.Subscription.RenewedTo = options.Subscription; u.Subscription.RenewedToDuration = options.Duration; repo.Update(u); this.CreatePaymentHistoryEntry(u.Id, options, amount, charge.StripeCard != null ? string.Format("{0} (xxxx xxxx xxxx {1})", charge.StripeCard.Type, charge.StripeCard.Last4) : null, charge.Id, false); } } else { reason = ChargeException.ChargeFailureReason.BadRequest; } } catch (Exception ex) { OnChargeException(ex, userId, options.Subscription, token, u, charge); } } else { reason = ChargeException.ChargeFailureReason.BadRequest; } } } else { reason = ChargeException.ChargeFailureReason.BadRequest; } if (reason.HasValue) { OnChargeException(new InvalidOperationException("Charge failed (general failure)."), userId, options.Subscription, token, u, charge, reason.Value); } }