/// <summary> /// Constructs the Freshbooks API authentication and wrapper class /// </summary> /// <param name="accountName">The account name for which you are trying to access</param> /// <param name="consumerKey">The developer's freshbooks account name</param> /// <param name="oauthSecret">The developer's oauth-secret provided by freshbooks</param> public FreshbooksApi(string accountName, string consumerKey, string oauthSecret) { _accountName = accountName; _consumerKey = consumerKey; _oauthSecret = oauthSecret ?? String.Empty; _baseUri = new UriBuilder { Scheme = "https", Host = accountName + ".freshbooks.com" }.Uri; _serviceUri = new Uri(_baseUri, "/api/2.1/xml-in"); Clear(); UserAgent = String.Format("{0}/{1} ({2})", GetType().Name, GetType().Assembly.GetName().Version.ToString(2), GetType().Assembly.FullName); Callback = new CallbackService(new ServiceProxy(this, "callback")); Category = new CategoryService(new ServiceProxy(this, "category")); Client = new ClientService(new ServiceProxy(this, "client")); Estimate = new EstimateService(new ServiceProxy(this, "estimate")); Expense = new ExpenseService(new ServiceProxy(this, "expense")); Gateway = new GatewayService(new ServiceProxy(this, "gateway")); Invoice = new InvoiceService(new ServiceProxy(this, "invoice")); Item = new ItemService(new ServiceProxy(this, "item")); Language = new LanguageService(new ServiceProxy(this, "language")); Payment = new PaymentService(new ServiceProxy(this, "payment")); Project = new ProjectService(new ServiceProxy(this, "project")); Recurring = new RecurringService(new ServiceProxy(this, "recurring")); System = new SystemService(new ServiceProxy(this, "system")); Staff = new StaffService(new ServiceProxy(this, "staff")); Task = new TaskService(new ServiceProxy(this, "task")); Tax = new TaxService(new ServiceProxy(this, "tax")); TimeEntry = new TimeEntryService(new ServiceProxy(this, "time_entry")); }
public DataServices(DbContext ctx) { DataContext = ctx as BizConnectEntities; Layouts = new LayoutService(DataContext); InvoiceData = new InvoiceDataService(DataContext); Client = new ClientService(DataContext); Invoice = new InvoiceService(DataContext); }
public void Start() { var invoiceService = new InvoiceService(); var currCustomer = _controller.GetCurrentCustomer(); invoiceService.SendInvoice(currCustomer); invoiceService.Shutdown(); }
/// <summary> /// Refresh the data from the API by sending Async calls /// </summary> /// <remarks></remarks> public void RefreshData() { ShowSpinner(); string pageFilter = string.Format("$top={0}&$skip={1}&$orderby=Date desc", PageSize, PageSize*(_currentPage - 1)); var invoiceSvc = new InvoiceService(MyConfiguration, null, MyOAuthKeyService); invoiceSvc.GetRange(MyCompanyFile, pageFilter, MyCredentials, OnComplete, OnError); }
public static async void ProcessQueueMessage([QueueTrigger("%invoicequeuename%")] Invoice invoice, TextWriter log) { log.WriteLine(String.Format("Generate new invoice for {0}", invoice.EmployeeName)); var invoiceService = new InvoiceService(); var file = await invoiceService.Create(invoice); if (file != null) { SharePointUploader.UploadFile(file, String.Format("invoice_{0}.pdf", invoice.RideId)); } }
public ServiceList(string url, ResponseToken token) { this.eventService = new EventService(url, token); this.categoryService = new CategoryService(url, token); this.clubService = new ClubService(url, token); this.userService = new UserService(url, token); this.ticketService = new TicketService(url, token); this.meetingService = new MeetingService(url, token); this.invoiceService = new InvoiceService(url, token); this.groupService = new GroupService(url, token); this.expenseService = new ExpenseService(url, token); this.emailService = new EmailService(url, token); this.depositService = new DepositService(url, token); this.customFieldService = new CustomFieldService(url, token); this.taskService = new TaskService(url, token); this.contactService = new ContactService(url, token); }
public async Task <BillingInfo> GetBillingAsync(ISubscriber subscriber) { var billingInfo = new BillingInfo(); ICollection <Transaction> transactions = null; if (subscriber is User) { transactions = await _transactionRepository.GetManyByUserIdAsync(subscriber.Id); } else if (subscriber is Organization) { transactions = await _transactionRepository.GetManyByOrganizationIdAsync(subscriber.Id); } if (transactions != null) { billingInfo.Transactions = transactions?.OrderByDescending(i => i.CreationDate) .Select(t => new BillingInfo.BillingTransaction(t)); } var customerService = new CustomerService(); var subscriptionService = new SubscriptionService(); var chargeService = new ChargeService(); var invoiceService = new InvoiceService(); if (!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId)) { var customer = await customerService.GetAsync(subscriber.GatewayCustomerId); if (customer != null) { billingInfo.Balance = customer.AccountBalance / 100M; if (customer.Metadata?.ContainsKey("btCustomerId") ?? false) { try { var braintreeCustomer = await _btGateway.Customer.FindAsync( customer.Metadata["btCustomerId"]); if (braintreeCustomer?.DefaultPaymentMethod != null) { billingInfo.PaymentSource = new BillingInfo.BillingSource( braintreeCustomer.DefaultPaymentMethod); } } catch (Braintree.Exceptions.NotFoundException) { } } else if (!string.IsNullOrWhiteSpace(customer.DefaultSourceId) && customer.Sources?.Data != null) { if (customer.DefaultSourceId.StartsWith("card_") || customer.DefaultSourceId.StartsWith("ba_")) { var source = customer.Sources.Data.FirstOrDefault(s => (s is Card || s is BankAccount) && s.Id == customer.DefaultSourceId); if (source != null) { billingInfo.PaymentSource = new BillingInfo.BillingSource(source); } } } var invoices = await invoiceService.ListAsync(new InvoiceListOptions { CustomerId = customer.Id, Limit = 20 }); billingInfo.Invoices = invoices?.Data?.OrderByDescending(i => i.Date) .Select(i => new BillingInfo.BillingInvoice(i)); } } return(billingInfo); }
/// <summary> /// Initializes a new instance of the <see cref="DynamicFulfilledOrderCollectionProvider"/> class. /// </summary> /// <param name="merchelloContext"> /// The merchello context. /// </param> /// <param name="collectionKey"> /// The collection key. /// </param> public DynamicFulfilledOrderCollectionProvider(IMerchelloContext merchelloContext, Guid collectionKey) : base(merchelloContext, collectionKey) { _invoiceService = (InvoiceService)merchelloContext.Services.InvoiceService; }
public IHttpActionResult AddInvoice() { try { var form = HttpContext.Current.Request.Form; var clientAddress = form.Get("ClientAddress"); var dueAmount = form.Get("UnpaidBalance"); var month = form.Get("InvoiceMonth"); var clientToAddress = form.Get("ClientToAddress"); if (dueAmount == "null") { dueAmount = 0.ToString(); } var CurrentAmount = form.Get("CurrentAmount"); var serviceId = form.Get("ClientService"); var createdBy = form.Get("CreatedBy"); var invoiceSer = JsonConvert.DeserializeObject<List<string>>(form.Get("InvoiceServices")); using (MaxMasterDbEntities db = new MaxMasterDbEntities()) { Invoice inData = new Invoice(); InvoiceService inService = new InvoiceService(); inData.Client_Id = Convert.ToInt32(form.Get("Client_Id")); inData.Id = form.Get("InvoiceId"); ; inData.CompanyAddress = form.Get("CompanyAddress"); inData.ClientAddress = clientAddress; inData.InvoiceCreatedBy = (from Emp in db.Employees where Emp.EmployeeNumber == createdBy select Emp.Id).FirstOrDefault(); inData.InvoiceCreatedDate = DateTime.Now; inData.InvoiceMonth = month; inData.InvoiceYear = Convert.ToInt32(form.Get("invoiceYear")); string currency = (from client in db.Clients where client.Id == inData.Client_Id select client.Currency).FirstOrDefault(); inData.CurrencyType = currency; inData.CurrentBillAmount = Convert.ToDecimal(CurrentAmount); inData.TotalDueAmount = Convert.ToDecimal(dueAmount); var totalInvoice = Convert.ToDecimal(CurrentAmount) + Convert.ToDecimal(dueAmount); inData.TotalInvoiceAmount = Convert.ToDecimal(totalInvoice); inData.Status = "Generated"; foreach (string id in invoiceSer) { string unitprice = (from client in db.Clients where client.Id == inData.Client_Id select client.PaymentAmount).FirstOrDefault().ToString(); inService.InvoiceId = inData.Id; inService.ClientId = Convert.ToInt32(form.Get("Client_Id")); inService.ServiceId = Convert.ToInt32(serviceId); inService.UnitPrice = Convert.ToDecimal(form.Get("UnitPrice")); inService.TotalLines = Convert.ToInt32(form.Get("TotalLines")); inService.BillAmount = Convert.ToDecimal(CurrentAmount); inService.DueAmount = inService.BillAmount; } db.Invoices.Add(inData); db.InvoiceServices.Add(inService); db.SaveChanges(); } return Ok(); } catch (Exception ex) { new Error().logAPIError(System.Reflection.MethodBase.GetCurrentMethod().Name, ex.ToString(), ex.StackTrace); return InternalServerError(); } }
private async Task <bool> AttemptToPayInvoiceWithBraintreeAsync(Invoice invoice) { var customerService = new CustomerService(); var customer = await customerService.GetAsync(invoice.CustomerId); if (!customer?.Metadata?.ContainsKey("btCustomerId") ?? true) { return(false); } var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); var ids = GetIdsFromMetaData(subscription?.Metadata); if (!ids.Item1.HasValue && !ids.Item2.HasValue) { return(false); } var btObjIdField = ids.Item1.HasValue ? "organization_id" : "user_id"; var btObjId = ids.Item1 ?? ids.Item2.Value; var btInvoiceAmount = (invoice.AmountDue / 100M); var transactionResult = await _btGateway.Transaction.SaleAsync( new Braintree.TransactionRequest { Amount = btInvoiceAmount, CustomerId = customer.Metadata["btCustomerId"], Options = new Braintree.TransactionOptionsRequest { SubmitForSettlement = true, PayPal = new Braintree.TransactionOptionsPayPalRequest { CustomField = $"{btObjIdField}:{btObjId}" } }, CustomFields = new Dictionary <string, string> { [btObjIdField] = btObjId.ToString() } }); if (!transactionResult.IsSuccess()) { if (invoice.AttemptCount < 4) { await _mailService.SendPaymentFailedAsync(customer.Email, btInvoiceAmount, true); } return(false); } try { var invoiceService = new InvoiceService(); await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = new Dictionary <string, string> { ["btTransactionId"] = transactionResult.Target.Id, ["btPayPalTransactionId"] = transactionResult.Target.PayPalDetails?.AuthorizationId } }); await invoiceService.PayAsync(invoice.Id, new InvoicePayOptions { PaidOutOfBand = true }); } catch (Exception e) { await _btGateway.Transaction.RefundAsync(transactionResult.Target.Id); throw e; } return(true); }
public async Task UpdateSubscription(string subscriptionId, string newPlanId, decimal newAmount, string interval) { var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(subscriptionId); if (!await DoesPlanExistAsync(newPlanId)) { await CreatePlanAsync(newPlanId, newAmount, interval, ProductName); } var oldPlanId = subscription.Items.Data[0].Plan.Id; await subscriptionService.UpdateAsync(subscriptionId, new SubscriptionUpdateOptions { CancelAtPeriodEnd = false, Items = new List <SubscriptionItemUpdateOption> { new SubscriptionItemUpdateOption { Id = subscription.Items.Data[0].Id, PlanId = newPlanId } } }); var invoiceService = new InvoiceService(); var invoice = await invoiceService.CreateAsync(new InvoiceCreateOptions { SubscriptionId = subscription.Id, CustomerId = subscription.CustomerId }); if (!invoice.Paid) { invoice = await invoiceService.PayAsync(invoice.Id, null); if (!invoice.Paid) { await subscriptionService.UpdateAsync(subscriptionId, new SubscriptionUpdateOptions { CancelAtPeriodEnd = false, Items = new List <SubscriptionItemUpdateOption> { new SubscriptionItemUpdateOption { Id = subscription.Items.Data[0].Id, PlanId = oldPlanId } } }); throw new UserFriendlyException(L("PaymentCouldNotCompleted")); } } var lastRecurringPayment = await _subscriptionPaymentRepository.GetByGatewayAndPaymentIdAsync(SubscriptionPaymentGatewayType.Stripe, subscriptionId); var payment = await _subscriptionPaymentRepository.GetLastPaymentOrDefaultAsync( tenantId : lastRecurringPayment.TenantId, SubscriptionPaymentGatewayType.Stripe, isRecurring : true); payment.Amount = ConvertFromStripePrice(invoice.Total); payment.IsRecurring = false; payment.ExternalPaymentId = invoice.ChargeId; payment.SetAsPaid(); }
public async Task <ActionResult <Invoice> > GetInvoiceAsync(string id) { if (!_options.StripeOptions.EnableBilling) { return(NotFound()); } if (!id.StartsWith("in_")) { id = "in_" + id; } Stripe.Invoice stripeInvoice = null; try { var client = new StripeClient(_options.StripeOptions.StripeApiKey); var invoiceService = new InvoiceService(client); stripeInvoice = await invoiceService.GetAsync(id); } catch (Exception ex) { using (_logger.BeginScope(new ExceptionlessState().Tag("Invoice").Identity(CurrentUser.EmailAddress).Property("User", CurrentUser).SetHttpContext(HttpContext))) _logger.LogError(ex, "An error occurred while getting the invoice: {InvoiceId}", id); } if (String.IsNullOrEmpty(stripeInvoice?.CustomerId)) { return(NotFound()); } var organization = await _repository.GetByStripeCustomerIdAsync(stripeInvoice.CustomerId); if (organization == null || !CanAccessOrganization(organization.Id)) { return(NotFound()); } var invoice = new Invoice { Id = stripeInvoice.Id.Substring(3), OrganizationId = organization.Id, OrganizationName = organization.Name, Date = stripeInvoice.Created, Paid = stripeInvoice.Paid, Total = stripeInvoice.Total / 100.0m }; foreach (var line in stripeInvoice.Lines.Data) { var item = new InvoiceLineItem { Amount = line.Amount / 100.0m }; if (line.Plan != null) { string planName = line.Plan.Nickname ?? _billingManager.GetBillingPlan(line.Plan.Id)?.Name; item.Description = $"Exceptionless - {planName} Plan ({(line.Plan.Amount / 100.0):c}/{line.Plan.Interval})"; } else { item.Description = line.Description; } item.Date = $"{(line.Period.Start ?? stripeInvoice.PeriodStart).ToShortDateString()} - {(line.Period.End ?? stripeInvoice.PeriodEnd).ToShortDateString()}"; invoice.Items.Add(item); } var coupon = stripeInvoice.Discount?.Coupon; if (coupon != null) { if (coupon.AmountOff.HasValue) { decimal discountAmount = coupon.AmountOff.GetValueOrDefault() / 100.0m; string description = $"{coupon.Id} ({discountAmount.ToString("C")} off)"; invoice.Items.Add(new InvoiceLineItem { Description = description, Amount = discountAmount }); } else { decimal discountAmount = (stripeInvoice.Subtotal / 100.0m) * (coupon.PercentOff.GetValueOrDefault() / 100.0m); string description = $"{coupon.Id} ({coupon.PercentOff.GetValueOrDefault()}% off)"; invoice.Items.Add(new InvoiceLineItem { Description = description, Amount = discountAmount }); } } return(Ok(invoice)); }
public async Task <IActionResult> PostWebhook([FromQuery] string key) { if (key != _billingSettings.StripeWebhookKey) { return(new BadRequestResult()); } Stripe.Event parsedEvent; using (var sr = new StreamReader(HttpContext.Request.Body)) { var json = await sr.ReadToEndAsync(); parsedEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], _billingSettings.StripeWebhookSecret); } if (string.IsNullOrWhiteSpace(parsedEvent?.Id)) { _logger.LogWarning("No event id."); return(new BadRequestResult()); } if (_hostingEnvironment.IsProduction() && !parsedEvent.Livemode) { _logger.LogWarning("Getting test events in production."); return(new BadRequestResult()); } var subDeleted = parsedEvent.Type.Equals("customer.subscription.deleted"); var subUpdated = parsedEvent.Type.Equals("customer.subscription.updated"); if (subDeleted || subUpdated) { var subscription = await GetSubscriptionAsync(parsedEvent, true); var ids = GetIdsFromMetaData(subscription.Metadata); var subCanceled = subDeleted && subscription.Status == "canceled"; var subUnpaid = subUpdated && subscription.Status == "unpaid"; var subIncompleteExpired = subUpdated && subscription.Status == "incomplete_expired"; if (subCanceled || subUnpaid || subIncompleteExpired) { // org if (ids.Item1.HasValue) { await _organizationService.DisableAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); } // user else if (ids.Item2.HasValue) { await _userService.DisablePremiumAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } if (subUpdated) { // org if (ids.Item1.HasValue) { await _organizationService.UpdateExpirationDateAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); } // user else if (ids.Item2.HasValue) { await _userService.UpdatePremiumExpirationAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } } else if (parsedEvent.Type.Equals("invoice.upcoming")) { var invoice = await GetInvoiceAsync(parsedEvent); var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); if (subscription == null) { throw new Exception("Invoice subscription is null. " + invoice.Id); } subscription = await VerifyCorrectTaxRateForCharge(invoice, subscription); string email = null; var ids = GetIdsFromMetaData(subscription.Metadata); // org if (ids.Item1.HasValue) { var org = await _organizationRepository.GetByIdAsync(ids.Item1.Value); if (org != null && OrgPlanForInvoiceNotifications(org)) { email = org.BillingEmail; } } // user else if (ids.Item2.HasValue) { var user = await _userService.GetUserByIdAsync(ids.Item2.Value); if (user.Premium) { email = user.Email; } } if (!string.IsNullOrWhiteSpace(email) && invoice.NextPaymentAttempt.HasValue) { var items = invoice.Lines.Select(i => i.Description).ToList(); await _mailService.SendInvoiceUpcomingAsync(email, invoice.AmountDue / 100M, invoice.NextPaymentAttempt.Value, items, true); } } else if (parsedEvent.Type.Equals("charge.succeeded")) { var charge = await GetChargeAsync(parsedEvent); var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, charge.Id); if (chargeTransaction != null) { _logger.LogWarning("Charge success already processed. " + charge.Id); return(new OkResult()); } Tuple <Guid?, Guid?> ids = null; Subscription subscription = null; var subscriptionService = new SubscriptionService(); if (charge.InvoiceId != null) { var invoiceService = new InvoiceService(); var invoice = await invoiceService.GetAsync(charge.InvoiceId); if (invoice?.SubscriptionId != null) { subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); ids = GetIdsFromMetaData(subscription?.Metadata); } } if (subscription == null || ids == null || (ids.Item1.HasValue && ids.Item2.HasValue)) { var subscriptions = await subscriptionService.ListAsync(new SubscriptionListOptions { Customer = charge.CustomerId }); foreach (var sub in subscriptions) { if (sub.Status != "canceled" && sub.Status != "incomplete_expired") { ids = GetIdsFromMetaData(sub.Metadata); if (ids.Item1.HasValue || ids.Item2.HasValue) { subscription = sub; break; } } } } if (!ids.Item1.HasValue && !ids.Item2.HasValue) { _logger.LogWarning("Charge success has no subscriber ids. " + charge.Id); return(new BadRequestResult()); } var tx = new Transaction { Amount = charge.Amount / 100M, CreationDate = charge.Created, OrganizationId = ids.Item1, UserId = ids.Item2, Type = TransactionType.Charge, Gateway = GatewayType.Stripe, GatewayId = charge.Id }; if (charge.Source != null && charge.Source is Card card) { tx.PaymentMethodType = PaymentMethodType.Card; tx.Details = $"{card.Brand}, *{card.Last4}"; } else if (charge.Source != null && charge.Source is BankAccount bankAccount) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"{bankAccount.BankName}, *{bankAccount.Last4}"; } else if (charge.Source != null && charge.Source is Source source) { if (source.Card != null) { tx.PaymentMethodType = PaymentMethodType.Card; tx.Details = $"{source.Card.Brand}, *{source.Card.Last4}"; } else if (source.AchDebit != null) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"{source.AchDebit.BankName}, *{source.AchDebit.Last4}"; } else if (source.AchCreditTransfer != null) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"ACH => {source.AchCreditTransfer.BankName}, " + $"{source.AchCreditTransfer.AccountNumber}"; } } else if (charge.PaymentMethodDetails != null) { if (charge.PaymentMethodDetails.Card != null) { tx.PaymentMethodType = PaymentMethodType.Card; tx.Details = $"{charge.PaymentMethodDetails.Card.Brand?.ToUpperInvariant()}, " + $"*{charge.PaymentMethodDetails.Card.Last4}"; } else if (charge.PaymentMethodDetails.AchDebit != null) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"{charge.PaymentMethodDetails.AchDebit.BankName}, " + $"*{charge.PaymentMethodDetails.AchDebit.Last4}"; } else if (charge.PaymentMethodDetails.AchCreditTransfer != null) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"ACH => {charge.PaymentMethodDetails.AchCreditTransfer.BankName}, " + $"{charge.PaymentMethodDetails.AchCreditTransfer.AccountNumber}"; } } if (!tx.PaymentMethodType.HasValue) { _logger.LogWarning("Charge success from unsupported source/method. " + charge.Id); return(new OkResult()); } try { await _transactionRepository.CreateAsync(tx); } // Catch foreign key violations because user/org could have been deleted. catch (SqlException e) when(e.Number == 547) { } } else if (parsedEvent.Type.Equals("charge.refunded")) { var charge = await GetChargeAsync(parsedEvent); var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, charge.Id); if (chargeTransaction == null) { throw new Exception("Cannot find refunded charge. " + charge.Id); } var amountRefunded = charge.AmountRefunded / 100M; if (!chargeTransaction.Refunded.GetValueOrDefault() && chargeTransaction.RefundedAmount.GetValueOrDefault() < amountRefunded) { chargeTransaction.RefundedAmount = amountRefunded; if (charge.Refunded) { chargeTransaction.Refunded = true; } await _transactionRepository.ReplaceAsync(chargeTransaction); foreach (var refund in charge.Refunds) { var refundTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, refund.Id); if (refundTransaction != null) { continue; } await _transactionRepository.CreateAsync(new Transaction { Amount = refund.Amount / 100M, CreationDate = refund.Created, OrganizationId = chargeTransaction.OrganizationId, UserId = chargeTransaction.UserId, Type = TransactionType.Refund, Gateway = GatewayType.Stripe, GatewayId = refund.Id, PaymentMethodType = chargeTransaction.PaymentMethodType, Details = chargeTransaction.Details }); } } else { _logger.LogWarning("Charge refund amount doesn't seem correct. " + charge.Id); } } else if (parsedEvent.Type.Equals("invoice.payment_succeeded")) { var invoice = await GetInvoiceAsync(parsedEvent, true); if (invoice.Paid && invoice.BillingReason == "subscription_create") { var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); if (subscription?.Status == "active") { if (DateTime.UtcNow - invoice.Created < TimeSpan.FromMinutes(1)) { await Task.Delay(5000); } var ids = GetIdsFromMetaData(subscription.Metadata); // org if (ids.Item1.HasValue) { if (subscription.Items.Any(i => StaticStore.Plans.Any(p => p.StripePlanId == i.Plan.Id))) { await _organizationService.EnableAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); } } // user else if (ids.Item2.HasValue) { if (subscription.Items.Any(i => i.Plan.Id == "premium-annually")) { await _userService.EnablePremiumAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } if (ids.Item1.HasValue || ids.Item2.HasValue) { await _referenceEventService.RaiseEventAsync( new ReferenceEvent(ReferenceEventType.Rebilled, null) { Id = ids.Item1 ?? ids.Item2 ?? default, Source = ids.Item1.HasValue ? ReferenceEventSource.Organization : ReferenceEventSource.User, });
private async Task <bool> AttemptToPayInvoiceWithAppleReceiptAsync(Invoice invoice, Customer customer) { if (!customer?.Metadata?.ContainsKey("appleReceipt") ?? true) { return(false); } var originalAppleReceiptTransactionId = customer.Metadata["appleReceipt"]; var appleReceiptRecord = await _appleIapService.GetReceiptAsync(originalAppleReceiptTransactionId); if (string.IsNullOrWhiteSpace(appleReceiptRecord?.Item1) || !appleReceiptRecord.Item2.HasValue) { return(false); } var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); var ids = GetIdsFromMetaData(subscription?.Metadata); if (!ids.Item2.HasValue) { // Apple receipt is only for user subscriptions return(false); } if (appleReceiptRecord.Item2.Value != ids.Item2.Value) { _logger.LogError("User Ids for Apple Receipt and subscription do not match: {0} != {1}.", appleReceiptRecord.Item2.Value, ids.Item2.Value); return(false); } var appleReceiptStatus = await _appleIapService.GetVerifiedReceiptStatusAsync(appleReceiptRecord.Item1); if (appleReceiptStatus == null) { // TODO: cancel sub if receipt is cancelled? return(false); } var receiptExpiration = appleReceiptStatus.GetLastExpiresDate().GetValueOrDefault(DateTime.MinValue); var invoiceDue = invoice.DueDate.GetValueOrDefault(DateTime.MinValue); if (receiptExpiration <= invoiceDue) { _logger.LogWarning("Apple receipt expiration is before invoice due date. {0} <= {1}", receiptExpiration, invoiceDue); return(false); } var receiptLastTransactionId = appleReceiptStatus.GetLastTransactionId(); var existingTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.AppStore, receiptLastTransactionId); if (existingTransaction != null) { _logger.LogWarning("There is already an existing transaction for this Apple receipt.", receiptLastTransactionId); return(false); } var appleTransaction = appleReceiptStatus.BuildTransactionFromLastTransaction( PremiumPlanAppleIapPrice, ids.Item2.Value); appleTransaction.Type = TransactionType.Charge; var invoiceService = new InvoiceService(); try { await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = new Dictionary <string, string> { ["appleReceipt"] = appleReceiptStatus.GetOriginalTransactionId(), ["appleReceiptTransactionId"] = receiptLastTransactionId } }); await _transactionRepository.CreateAsync(appleTransaction); await invoiceService.PayAsync(invoice.Id, new InvoicePayOptions { PaidOutOfBand = true }); } catch (Exception e) { if (e.Message.Contains("Invoice is already paid")) { await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = invoice.Metadata }); } else { throw; } } return(true); }
public InvoiceController() { invoiceService = new InvoiceService(); commonService = new CommonService(); }
/// <summary> /// Deletes all invoices /// </summary> public void DeleteAllInvoices() { var all = ((InvoiceService)InvoiceService).GetAll().ToArray(); InvoiceService.Delete(all); }
public async Task <bool> PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber, string planId, List <InvoiceSubscriptionItemOptions> subItemOptions, int prorateThreshold = 500) { var invoiceService = new InvoiceService(); var invoiceItemService = new InvoiceItemService(); var pendingInvoiceItems = invoiceItemService.ListAutoPaging(new InvoiceItemListOptions { CustomerId = subscriber.GatewayCustomerId }).ToList().Where(i => i.InvoiceId == null); var pendingInvoiceItemsDict = pendingInvoiceItems.ToDictionary(pii => pii.Id); var upcomingPreview = await invoiceService.UpcomingAsync(new UpcomingInvoiceOptions { CustomerId = subscriber.GatewayCustomerId, SubscriptionId = subscriber.GatewaySubscriptionId, SubscriptionItems = subItemOptions }); var itemsForInvoice = upcomingPreview.Lines?.Data? .Where(i => pendingInvoiceItemsDict.ContainsKey(i.Id) || (i.Plan.Id == planId && i.Proration)); var invoiceAmount = itemsForInvoice?.Sum(i => i.Amount) ?? 0; var invoiceNow = invoiceAmount >= prorateThreshold; if (invoiceNow) { // Owes more than prorateThreshold on next invoice. // Invoice them and pay now instead of waiting until next billing cycle. Invoice invoice = null; var createdInvoiceItems = new List <InvoiceItem>(); Braintree.Transaction braintreeTransaction = null; try { foreach (var ii in itemsForInvoice) { if (pendingInvoiceItemsDict.ContainsKey(ii.Id)) { continue; } var invoiceItem = await invoiceItemService.CreateAsync(new InvoiceItemCreateOptions { Currency = ii.Currency, Description = ii.Description, CustomerId = subscriber.GatewayCustomerId, SubscriptionId = ii.SubscriptionId, Discountable = ii.Discountable, Amount = ii.Amount }); createdInvoiceItems.Add(invoiceItem); } invoice = await invoiceService.CreateAsync(new InvoiceCreateOptions { Billing = Billing.SendInvoice, DaysUntilDue = 1, CustomerId = subscriber.GatewayCustomerId, SubscriptionId = subscriber.GatewaySubscriptionId }); var invoicePayOptions = new InvoicePayOptions(); var customerService = new CustomerService(); var customer = await customerService.GetAsync(subscriber.GatewayCustomerId); if (customer != null) { if (customer.Metadata.ContainsKey("btCustomerId")) { invoicePayOptions.PaidOutOfBand = true; var btInvoiceAmount = (invoiceAmount / 100M); var transactionResult = await _btGateway.Transaction.SaleAsync( new Braintree.TransactionRequest { Amount = btInvoiceAmount, CustomerId = customer.Metadata["btCustomerId"], Options = new Braintree.TransactionOptionsRequest { SubmitForSettlement = true, PayPal = new Braintree.TransactionOptionsPayPalRequest { CustomField = $"{subscriber.BraintreeIdField()}:{subscriber.Id}" } }, CustomFields = new Dictionary <string, string> { [subscriber.BraintreeIdField()] = subscriber.Id.ToString() } }); if (!transactionResult.IsSuccess()) { throw new GatewayException("Failed to charge PayPal customer."); } braintreeTransaction = transactionResult.Target; await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = new Dictionary <string, string> { ["btTransactionId"] = braintreeTransaction.Id, ["btPayPalTransactionId"] = braintreeTransaction.PayPalDetails.AuthorizationId } }); } } await invoiceService.PayAsync(invoice.Id, invoicePayOptions); } catch (Exception e) { if (braintreeTransaction != null) { await _btGateway.Transaction.RefundAsync(braintreeTransaction.Id); } if (invoice != null) { await invoiceService.DeleteAsync(invoice.Id); // Restore invoice items that were brought in foreach (var item in pendingInvoiceItems) { var i = new InvoiceItemCreateOptions { Currency = item.Currency, Description = item.Description, CustomerId = item.CustomerId, SubscriptionId = item.SubscriptionId, Discountable = item.Discountable, Metadata = item.Metadata, Quantity = item.Quantity, UnitAmount = item.UnitAmount }; await invoiceItemService.CreateAsync(i); } } else { foreach (var ii in createdInvoiceItems) { await invoiceItemService.DeleteAsync(ii.Id); } } throw e; } } return(invoiceNow); }
public async Task PurchaseOrganizationAsync(Organization org, PaymentMethodType paymentMethodType, string paymentToken, Models.StaticStore.Plan plan, short additionalStorageGb, short additionalSeats, bool premiumAccessAddon) { var invoiceService = new InvoiceService(); var customerService = new CustomerService(); Braintree.Customer braintreeCustomer = null; string stipeCustomerSourceToken = null; var stripeCustomerMetadata = new Dictionary <string, string>(); var stripePaymentMethod = paymentMethodType == PaymentMethodType.Card || paymentMethodType == PaymentMethodType.BankAccount; if (stripePaymentMethod) { stipeCustomerSourceToken = paymentToken; } else if (paymentMethodType == PaymentMethodType.PayPal) { var randomSuffix = Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false); var customerResult = await _btGateway.Customer.CreateAsync(new Braintree.CustomerRequest { PaymentMethodNonce = paymentToken, Email = org.BillingEmail, Id = org.BraintreeCustomerIdPrefix() + org.Id.ToString("N").ToLower() + randomSuffix, CustomFields = new Dictionary <string, string> { [org.BraintreeIdField()] = org.Id.ToString() } }); if (!customerResult.IsSuccess() || customerResult.Target.PaymentMethods.Length == 0) { throw new GatewayException("Failed to create PayPal customer record."); } braintreeCustomer = customerResult.Target; stripeCustomerMetadata.Add("btCustomerId", braintreeCustomer.Id); } else { throw new GatewayException("Payment method is not supported at this time."); } var subCreateOptions = new SubscriptionCreateOptions { TrialPeriodDays = plan.TrialPeriodDays, Items = new List <SubscriptionItemOption>(), Metadata = new Dictionary <string, string> { [org.GatewayIdField()] = org.Id.ToString() } }; if (plan.StripePlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripePlanId, Quantity = 1 }); } if (additionalSeats > 0 && plan.StripeSeatPlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripeSeatPlanId, Quantity = additionalSeats }); } if (additionalStorageGb > 0) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripeStoragePlanId, Quantity = additionalStorageGb }); } if (premiumAccessAddon && plan.StripePremiumAccessPlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripePremiumAccessPlanId, Quantity = 1 }); } Customer customer = null; Subscription subscription = null; try { customer = await customerService.CreateAsync(new CustomerCreateOptions { Description = org.BusinessName, Email = org.BillingEmail, SourceToken = stipeCustomerSourceToken, Metadata = stripeCustomerMetadata }); subCreateOptions.CustomerId = customer.Id; var subscriptionService = new SubscriptionService(); subscription = await subscriptionService.CreateAsync(subCreateOptions); } catch (Exception e) { if (customer != null) { await customerService.DeleteAsync(customer.Id); } if (braintreeCustomer != null) { await _btGateway.Customer.DeleteAsync(braintreeCustomer.Id); } throw e; } org.Gateway = GatewayType.Stripe; org.GatewayCustomerId = customer.Id; org.GatewaySubscriptionId = subscription.Id; org.ExpirationDate = subscription.CurrentPeriodEnd; }
public async Task<IHttpActionResult> GenerateInvoiceForAJob(string jobhrid) { var job = await repository.GetJobByHrid(jobhrid); string customerName; if (job.User.Type == Data.Model.Identity.IdentityTypes.USER) customerName = (job.User.Profile as UserProfile)?.FullName; else if (job.User.Type == Data.Model.Identity.IdentityTypes.ENTERPRISE) customerName = (job.User.Profile as EnterpriseUserProfile)?.CompanyName; else { customerName = (job.User.Profile as AssetProfile)?.FullName; } if (job.Order.Type == OrderTypes.Delivery) { DeliveryOrder order = job.Order as DeliveryOrder; if (order.OrderCart == null) throw new InvalidOperationException("Generating invoice with blank order cart is not supported"); IInvoiceService invoiceService = new InvoiceService(); DeliveryInvoice invoice = invoiceService.GenerateInvoice<ItemDetailsInvoiceRequest, DeliveryInvoice>(new ItemDetailsInvoiceRequest() { CustomerName = customerName, DeliveryFrom = order.From, DeliveryTo = order.To, ItemDetails = order.OrderCart.PackageList, NetTotal = order.OrderCart.PackageList.Sum(x => x.Total), NotesToDeliveryMan = order.NoteToDeliveryMan, PaymentStatus = job.PaymentStatus, ServiceCharge = order.OrderCart.ServiceCharge, SubTotal = order.OrderCart.SubTotal, TotalToPay = order.OrderCart.TotalToPay, TotalVATAmount = order.OrderCart.TotalVATAmount, TotalWeight = order.OrderCart.TotalWeight, VendorName = "Anonymous" }); invoice.InvoiceId = job.HRID; IPDFService<DeliveryInvoice> DeliveryInvoicePrinter = new DeliveryInvoicePDFGenerator(); var invoiceStream = DeliveryInvoicePrinter.GeneratePDF(invoice); var reponseMessage = new HttpResponseMessage(HttpStatusCode.OK) { Content = new ByteArrayContent(invoiceStream.GetBuffer()) }; reponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = string.Concat(invoice.InvoiceId, ".pdf") }; reponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return ResponseMessage(reponseMessage); } else { throw new NotImplementedException($"Invoice for job type {job.Order.Type} is still not implemented"); } }
public ActionResult Pay(Payment item) { var me = (User)Session["me"]; if (me == null) { return(RedirectToAction("Index")); } var stripeToken = Request.Form["stripeToken"]; if (String.IsNullOrEmpty(stripeToken)) { TempData["result_code"] = -1; TempData["message"] = "Stripe set an error with your informations"; TempData.Keep(); return(RedirectToAction("Index")); } var Email = Request.Form["stripeEmail"]; var stripeTokenType = Request.Form["stripeTokenType"]; var productService = new ProductService(); var priceService = new PriceService(); var invoiceItemService = new InvoiceItemService(); var invoiceServices = new InvoiceService(); var customerService = new CustomerService(); var planService = new PlanService(); var subscriptionService = new SubscriptionService(); var original_amount = 500; var amount = Convert.ToInt32(me.reduction > 0 ? original_amount * me.reduction : original_amount); var product = productService.Create(new ProductCreateOptions { Name = "Name of Service", }); var price = priceService.Create(new PriceCreateOptions { Product = product.Id, UnitAmount = amount, Currency = "usd", Recurring = new PriceRecurringOptions { Interval = "month", }, }); var customer = customerService.Create(new CustomerCreateOptions { Email = Email, Source = stripeToken, }); var plan = planService.Create(new PlanCreateOptions { Amount = amount, Currency = "usd", Interval = "month", IntervalCount = 1, Product = product.Id, // "prod_IinH4BV2oyao8L", }); var subscription = subscriptionService.Create(new SubscriptionCreateOptions { Customer = customer.Id, Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Plan = plan.Id, }, }, }); if (subscription.Status == "active") { item.original_amount = 500; item.amount = amount; item.code = QRCodeModel.GenerateRandomString(); item.payer_id = me.id; db1.Payment.Add(item); db1.SaveChanges(); TempData["result_code"] = 1; TempData["message"] = "Subscription done successfully"; TempData.Keep(); return(RedirectToAction("Payments")); } TempData["result_code"] = -1; TempData["message"] = "An error occured during the payment"; TempData.Keep(); return(RedirectToAction("Index")); }
private void btnPaid_Click(object sender, EventArgs e) { CustomerService customerService = serviceFactory.GetCustomerService(); OrderService orderService = serviceFactory.GetOrderService(); InvoiceService invoiceService = serviceFactory.GetInvoiceService(); Customer customer; string temp = ""; if (rdbtnMale.Checked == true) { customer = new Customer((customerService.GetCustId() + 1), txtBxCustomerName.Text, "Male", txtBxCustomerPhone.Text); foreach (FoodItem fi in orderfoodItemList) { temp = temp + fi.Id; } if (customerService.StoreCustomerInfo(customer) == true) { Order or = new Order((orderService.GetOrderId() + 1), temp); if (orderService.StoreOrderInfo(or) == true) { Invoice inv = new Invoice((invoiceService.GetInvoiceId() + 1), Convert.ToDouble(lblTotalInf.Text), or.Id, customer.Id); if (invoiceService.StoreOrderInfo(inv) == true) { MessageBox.Show("Attempt successfull"); } else { customerService.DeleteCustomerInfo(or.Id); orderService.DeleteOrderInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } else { customerService.DeleteCustomerInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } } else if (rdbtnFemale.Checked == true) { customer = new Customer((customerService.GetCustId() + 1), txtBxCustomerName.Text, "Female", txtBxCustomerPhone.Text); foreach (FoodItem fi in orderfoodItemList) { temp = temp + fi.Id; } if (customerService.StoreCustomerInfo(customer) == true) { Order or = new Order((orderService.GetOrderId() + 1), temp); if (orderService.StoreOrderInfo(or) == true) { Invoice inv = new Invoice((invoiceService.GetInvoiceId() + 1), Convert.ToDouble(lblTotalInf.Text), or.Id, customer.Id); if (invoiceService.StoreOrderInfo(inv) == true) { MessageBox.Show("Attempt successfull"); } else { customerService.DeleteCustomerInfo(or.Id); orderService.DeleteOrderInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } else { customerService.DeleteCustomerInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } } else if (rdbtnOthers.Checked == true) { customer = new Customer((customerService.GetCustId() + 1), txtBxCustomerName.Text, "Other", txtBxCustomerPhone.Text); foreach (FoodItem fi in orderfoodItemList) { temp = temp + fi.Id; } if (customerService.StoreCustomerInfo(customer) == true) { Order or = new Order((orderService.GetOrderId() + 1), temp); if (orderService.StoreOrderInfo(or) == true) { Invoice inv = new Invoice((invoiceService.GetInvoiceId() + 1), Convert.ToDouble(lblTotalInf.Text), or.Id, customer.Id); if (invoiceService.StoreOrderInfo(inv) == true) { MessageBox.Show("Attempt successfull"); } else { customerService.DeleteCustomerInfo(or.Id); orderService.DeleteOrderInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } else { customerService.DeleteCustomerInfo(or.Id); MessageBox.Show("Attempt unsuccessfull"); } } } }
public InvoicesController(InvoiceService invoiceService, ClientService clientService) { this.invoiceService = invoiceService; this.clientService = clientService; }
public CountInvoiceController(TestContext testContext) { _invoiceService = new InvoiceService(testContext); }
private async Task <bool> AttemptToPayInvoiceWithBraintreeAsync(Invoice invoice, Customer customer) { if (!customer?.Metadata?.ContainsKey("btCustomerId") ?? true) { return(false); } var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); var ids = GetIdsFromMetaData(subscription?.Metadata); if (!ids.Item1.HasValue && !ids.Item2.HasValue) { return(false); } var orgTransaction = ids.Item1.HasValue; var btObjIdField = orgTransaction ? "organization_id" : "user_id"; var btObjId = ids.Item1 ?? ids.Item2.Value; var btInvoiceAmount = (invoice.AmountDue / 100M); var existingTransactions = orgTransaction ? await _transactionRepository.GetManyByOrganizationIdAsync(ids.Item1.Value) : await _transactionRepository.GetManyByUserIdAsync(ids.Item2.Value); var duplicateTimeSpan = TimeSpan.FromHours(24); var now = DateTime.UtcNow; var duplicateTransaction = existingTransactions? .FirstOrDefault(t => (now - t.CreationDate) < duplicateTimeSpan); if (duplicateTransaction != null) { _logger.LogWarning("There is already a recent PayPal transaction ({0}). " + "Do not charge again to prevent possible duplicate.", duplicateTransaction.GatewayId); return(false); } var transactionResult = await _btGateway.Transaction.SaleAsync( new Braintree.TransactionRequest { Amount = btInvoiceAmount, CustomerId = customer.Metadata["btCustomerId"], Options = new Braintree.TransactionOptionsRequest { SubmitForSettlement = true, PayPal = new Braintree.TransactionOptionsPayPalRequest { CustomField = $"{btObjIdField}:{btObjId}" } }, CustomFields = new Dictionary <string, string> { [btObjIdField] = btObjId.ToString() } }); if (!transactionResult.IsSuccess()) { if (invoice.AttemptCount < 4) { await _mailService.SendPaymentFailedAsync(customer.Email, btInvoiceAmount, true); } return(false); } var invoiceService = new InvoiceService(); try { await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = new Dictionary <string, string> { ["btTransactionId"] = transactionResult.Target.Id, ["btPayPalTransactionId"] = transactionResult.Target.PayPalDetails?.AuthorizationId } }); await invoiceService.PayAsync(invoice.Id, new InvoicePayOptions { PaidOutOfBand = true }); } catch (Exception e) { await _btGateway.Transaction.RefundAsync(transactionResult.Target.Id); if (e.Message.Contains("Invoice is already paid")) { await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = invoice.Metadata }); } else { throw; } } return(true); }
public void Setup() { this.invoiceService = new InvoiceService(); }
// # SendInvoice API Operation // Use the SendInvoice API operation to send an invoice to a payer, and notify the payer of the pending invoice. public SendInvoiceResponse SendInvoiceAPIOperation() { // Create the SendInvoiceResponse object SendInvoiceResponse responseSendInvoice = new SendInvoiceResponse(); try { // # SendInvoiceRequest // Use the SendInvoiceRequest message to send an invoice to a payer, and // notify the payer of the pending invoice. // The code for the language in which errors are returned, which must be // en_US. RequestEnvelope envelopeRequest = new RequestEnvelope(); envelopeRequest.errorLanguage = "en_US"; // SendInvoiceRequest which takes mandatory params: // // * `Request Envelope` - Information common to each API operation, such // as the language in which an error message is returned. // * `Invoice ID` - ID of the invoice to send. SendInvoiceRequest requestSendInvoice = new SendInvoiceRequest(envelopeRequest, "INV2-ZC9R-X6MS-RK8H-4VKJ"); // Create the service wrapper object to make the API call InvoiceService service = new InvoiceService(); // # API call // Invoke the SendInvoice method in service responseSendInvoice = service.SendInvoice(requestSendInvoice); if (responseSendInvoice != null) { // Response envelope acknowledgement string acknowledgement = "SendInvoice API Operation - "; acknowledgement += responseSendInvoice.responseEnvelope.ack.ToString(); logger.Info(acknowledgement + "\n"); Console.WriteLine(acknowledgement + "\n"); // # Success values if (responseSendInvoice.responseEnvelope.ack.ToString().Trim().ToUpper().Equals("SUCCESS")) { // ID of the created invoice. logger.Info("Invoice ID : " + responseSendInvoice.invoiceID + "\n"); Console.WriteLine("Invoice ID : " + responseSendInvoice.invoiceID + "\n"); } // # Error Values else { List <ErrorData> errorMessages = responseSendInvoice.error; foreach (ErrorData error in errorMessages) { logger.Debug("API Error Message : " + error.message); Console.WriteLine("API Error Message : " + error.message + "\n"); } } } } // # Exception log catch (System.Exception ex) { // Log the exception message logger.Debug("Error Message : " + ex.Message); Console.WriteLine("Error Message : " + ex.Message); } return(responseSendInvoice); }
public InvoiceServiceTest( StripeMockFixture stripeMockFixture, MockHttpClientFixture mockHttpClientFixture) : base(stripeMockFixture, mockHttpClientFixture) { this.service = new InvoiceService(this.StripeClient); this.createOptions = new InvoiceCreateOptions { Customer = "cus_123", TaxPercent = 12.5m, }; this.updateOptions = new InvoiceUpdateOptions { Metadata = new Dictionary <string, string> { { "key", "value" }, }, }; this.payOptions = new InvoicePayOptions { Forgive = true, Source = "src_123", }; this.listOptions = new InvoiceListOptions { Limit = 1, }; this.listLineItemsOptions = new InvoiceListLineItemsOptions { Limit = 1, }; this.upcomingOptions = new UpcomingInvoiceOptions { Customer = "cus_123", Subscription = "sub_123", }; this.upcomingListLineItemsOptions = new UpcomingInvoiceListLineItemsOptions { Limit = 1, Customer = "cus_123", Subscription = "sub_123", }; this.finalizeOptions = new InvoiceFinalizeOptions { }; this.markUncollectibleOptions = new InvoiceMarkUncollectibleOptions { }; this.sendOptions = new InvoiceSendOptions { }; this.voidOptions = new InvoiceVoidOptions { }; }
public InvoiceTollTariffsController(InvoiceNumberService invoiceNumSvc, ListReleaseInvoiceService listReleaseInvoiceSvc, TemplateInvoiceService templateInvoiceSvc, CustomerService cumtomerSvc, InvoiceService invoiceSvc, BanksService banksSvc, CurrencyService currencySvc, ProductService productSvc, UnitService unitSvc) { _unitSvc = unitSvc; _listReleaseInvoiceSvc = listReleaseInvoiceSvc; _templateInvoiceSvc = templateInvoiceSvc; _invoiceNumberSvc = invoiceNumSvc; _cumtomerSvc = cumtomerSvc; _invoiceSvc = invoiceSvc; _banksSvc = banksSvc; _currencySvc = currencySvc; _productSvc = productSvc; }
protected StripeWebhookEvent GetWebhookStripeEvent(HttpRequestBase request, string webhookSigningSecret) { StripeWebhookEvent stripeEvent = null; if (HttpContext.Current.Items["Vendr_StripeEvent"] != null) { stripeEvent = (StripeWebhookEvent)HttpContext.Current.Items["Vendr_StripeEvent"]; } else { try { if (request.InputStream.CanSeek) { request.InputStream.Seek(0, SeekOrigin.Begin); } using (var reader = new StreamReader(request.InputStream)) { var json = reader.ReadToEnd(); // Just validate the webhook signature EventUtility.ValidateSignature(json, request.Headers["Stripe-Signature"], webhookSigningSecret); // Parse the event ourselves to our custom webhook event model // as it only captures minimal object information. stripeEvent = JsonConvert.DeserializeObject <StripeWebhookEvent>(json); // We manually fetch the event object type ourself as it means it will be fetched // using the same API version as the payment providers is coded against. // NB: Only supports a number of object types we are likely to be interested in. if (stripeEvent?.Data?.Object != null) { switch (stripeEvent.Data.Object.Type) { case "checkout.session": var sessionService = new SessionService(); stripeEvent.Data.Object.Instance = sessionService.Get(stripeEvent.Data.Object.Id); break; case "charge": var chargeService = new ChargeService(); stripeEvent.Data.Object.Instance = chargeService.Get(stripeEvent.Data.Object.Id); break; case "payment_intent": var paymentIntentService = new PaymentIntentService(); stripeEvent.Data.Object.Instance = paymentIntentService.Get(stripeEvent.Data.Object.Id); break; case "subscription": var subscriptionService = new SubscriptionService(); stripeEvent.Data.Object.Instance = subscriptionService.Get(stripeEvent.Data.Object.Id); break; case "invoice": var invoiceService = new InvoiceService(); stripeEvent.Data.Object.Instance = invoiceService.Get(stripeEvent.Data.Object.Id); break; } } HttpContext.Current.Items["Vendr_StripeEvent"] = stripeEvent; } } catch (Exception ex) { Vendr.Log.Error <StripePaymentProviderBase <TSettings> >(ex, "Stripe - GetWebhookStripeEvent"); } } return(stripeEvent); }
public InvoicesController(InvoiceService invoiceService, InvoicesAuthorize invoiceAuthorize) { this.invoiceService = invoiceService; this.invoiceAuthorize = invoiceAuthorize; }
/// <summary> /// Initializes a new instance of the <see cref="DynamicPartiallyPaidInvoiceCollectionProvider"/> class. /// </summary> /// <param name="merchelloContext"> /// The merchello context. /// </param> /// <param name="collectionKey"> /// The collection key. /// </param> public DynamicPartiallyPaidInvoiceCollectionProvider(IMerchelloContext merchelloContext, Guid collectionKey) : base(merchelloContext, collectionKey) { _invoiceService = (InvoiceService)merchelloContext.Services.InvoiceService; }
public async Task <IActionResult> PostWebhook([FromQuery] string key) { if (key != _billingSettings.StripeWebhookKey) { return(new BadRequestResult()); } Stripe.Event parsedEvent; using (var sr = new StreamReader(HttpContext.Request.Body)) { var json = await sr.ReadToEndAsync(); parsedEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], _billingSettings.StripeWebhookSecret); } if (string.IsNullOrWhiteSpace(parsedEvent?.Id)) { return(new BadRequestResult()); } if (_hostingEnvironment.IsProduction() && !parsedEvent.Livemode) { return(new BadRequestResult()); } var subDeleted = parsedEvent.Type.Equals("customer.subscription.deleted"); var subUpdated = parsedEvent.Type.Equals("customer.subscription.updated"); if (subDeleted || subUpdated) { if (!(parsedEvent.Data.Object is Subscription subscription)) { throw new Exception("Subscription is null."); } var ids = GetIdsFromMetaData(subscription.Metadata); var subCanceled = subDeleted && subscription.Status == "canceled"; var subUnpaid = subUpdated && subscription.Status == "unpaid"; if (subCanceled || subUnpaid) { // org if (ids.Item1.HasValue) { await _organizationService.DisableAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); } // user else if (ids.Item2.HasValue) { await _userService.DisablePremiumAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } if (subUpdated) { // org if (ids.Item1.HasValue) { await _organizationService.UpdateExpirationDateAsync(ids.Item1.Value, subscription.CurrentPeriodEnd); } // user else if (ids.Item2.HasValue) { await _userService.UpdatePremiumExpirationAsync(ids.Item2.Value, subscription.CurrentPeriodEnd); } } } else if (parsedEvent.Type.Equals("invoice.upcoming")) { if (!(parsedEvent.Data.Object is Invoice invoice)) { throw new Exception("Invoice is null."); } var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); if (subscription == null) { throw new Exception("Invoice subscription is null."); } string email = null; var ids = GetIdsFromMetaData(subscription.Metadata); // org if (ids.Item1.HasValue) { var org = await _organizationRepository.GetByIdAsync(ids.Item1.Value); if (org != null && OrgPlanForInvoiceNotifications(org)) { email = org.BillingEmail; } } // user else if (ids.Item2.HasValue) { var user = await _userService.GetUserByIdAsync(ids.Item2.Value); if (user.Premium) { email = user.Email; } } if (!string.IsNullOrWhiteSpace(email) && invoice.NextPaymentAttempt.HasValue) { var items = invoice.Lines.Select(i => i.Description).ToList(); await _mailService.SendInvoiceUpcomingAsync(email, invoice.AmountDue / 100M, invoice.NextPaymentAttempt.Value, items, true); } } else if (parsedEvent.Type.Equals("charge.succeeded")) { if (!(parsedEvent.Data.Object is Charge charge)) { throw new Exception("Charge is null."); } var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, charge.Id); if (chargeTransaction != null) { return(new OkResult()); } Tuple <Guid?, Guid?> ids = null; Subscription subscription = null; var subscriptionService = new SubscriptionService(); if (charge.InvoiceId != null) { var invoiceService = new InvoiceService(); var invoice = await invoiceService.GetAsync(charge.InvoiceId); if (invoice?.SubscriptionId != null) { subscription = await subscriptionService.GetAsync(invoice.SubscriptionId); ids = GetIdsFromMetaData(subscription?.Metadata); } } if (subscription == null || ids == null || (ids.Item1.HasValue && ids.Item2.HasValue)) { var subscriptions = await subscriptionService.ListAsync(new SubscriptionListOptions { CustomerId = charge.CustomerId }); foreach (var sub in subscriptions) { if (sub.Status != "canceled") { ids = GetIdsFromMetaData(sub.Metadata); if (ids.Item1.HasValue || ids.Item2.HasValue) { subscription = sub; break; } } } } if (!ids.Item1.HasValue && !ids.Item2.HasValue) { return(new BadRequestResult()); } var tx = new Transaction { Amount = charge.Amount / 100M, CreationDate = charge.Created, OrganizationId = ids.Item1, UserId = ids.Item2, Type = TransactionType.Charge, Gateway = GatewayType.Stripe, GatewayId = charge.Id }; if (charge.Source is Card card) { tx.PaymentMethodType = PaymentMethodType.Card; tx.Details = $"{card.Brand}, *{card.Last4}"; } else if (charge.Source is BankAccount bankAccount) { tx.PaymentMethodType = PaymentMethodType.BankAccount; tx.Details = $"{bankAccount.BankName}, *{bankAccount.Last4}"; } else { return(new OkResult()); } try { await _transactionRepository.CreateAsync(tx); } // Catch foreign key violations because user/org could have been deleted. catch (SqlException e) when(e.Number == 547) { } } else if (parsedEvent.Type.Equals("charge.refunded")) { if (!(parsedEvent.Data.Object is Charge charge)) { throw new Exception("Charge is null."); } var chargeTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, charge.Id); if (chargeTransaction == null) { throw new Exception("Cannot find refunded charge."); } var amountRefunded = charge.AmountRefunded / 100M; if (!chargeTransaction.Refunded.GetValueOrDefault() && chargeTransaction.RefundedAmount.GetValueOrDefault() < amountRefunded) { chargeTransaction.RefundedAmount = amountRefunded; if (charge.Refunded) { chargeTransaction.Refunded = true; } await _transactionRepository.ReplaceAsync(chargeTransaction); foreach (var refund in charge.Refunds) { var refundTransaction = await _transactionRepository.GetByGatewayIdAsync( GatewayType.Stripe, refund.Id); if (refundTransaction != null) { continue; } await _transactionRepository.CreateAsync(new Transaction { Amount = refund.Amount / 100M, CreationDate = refund.Created, OrganizationId = chargeTransaction.OrganizationId, UserId = chargeTransaction.UserId, Type = TransactionType.Refund, Gateway = GatewayType.Stripe, GatewayId = refund.Id, PaymentMethodType = chargeTransaction.PaymentMethodType, Details = chargeTransaction.Details }); } } } else if (parsedEvent.Type.Equals("invoice.payment_failed")) { if (!(parsedEvent.Data.Object is Invoice invoice)) { throw new Exception("Invoice is null."); } if (invoice.AttemptCount > 1 && UnpaidAutoChargeInvoiceForSubscriptionCycle(invoice)) { await AttemptToPayInvoiceWithBraintreeAsync(invoice); } } else if (parsedEvent.Type.Equals("invoice.created")) { if (!(parsedEvent.Data.Object is Invoice invoice)) { throw new Exception("Invoice is null."); } if (UnpaidAutoChargeInvoiceForSubscriptionCycle(invoice)) { await AttemptToPayInvoiceWithBraintreeAsync(invoice); } } return(new OkResult()); }
public ActionResult <RetrieveUpcomingInvoiceResponse> RetrieveUpcomingInvoice([FromBody] RetrieveUpcomingInvoiceRequest req) { if (!ModelState.IsValid) { return(this.FailWithMessage("invalid params")); } var newPrice = Environment.GetEnvironmentVariable(req.NewPrice.ToUpper()); if (newPrice is null || newPrice == "") { return(this.FailWithMessage($"No price with the new price ID ({req.NewPrice}) found in .env")); } List <InvoiceSubscriptionItemOptions> items; Subscription subscription = null; if (req.Subscription != "" && req.Subscription != null) { var subscriptionService = new SubscriptionService(); subscription = subscriptionService.Get(req.Subscription); var currentPrice = subscription.Items.Data[0].Price.Id; if (currentPrice == newPrice) { items = new List <InvoiceSubscriptionItemOptions> { new InvoiceSubscriptionItemOptions { Id = subscription.Items.Data[0].Id, Quantity = req.Quantity, } }; } else { items = new List <InvoiceSubscriptionItemOptions> { new InvoiceSubscriptionItemOptions { Id = subscription.Items.Data[0].Id, Deleted = true, }, new InvoiceSubscriptionItemOptions { Price = newPrice, Quantity = req.Quantity, }, }; } } else { items = new List <InvoiceSubscriptionItemOptions> { new InvoiceSubscriptionItemOptions { Price = newPrice, Quantity = req.Quantity, }, }; } var invoiceService = new InvoiceService(); var options = new UpcomingInvoiceOptions { Customer = req.Customer, Subscription = req.Subscription, SubscriptionItems = items, }; Invoice upcomingInvoice = invoiceService.Upcoming(options); if (req.Subscription == "" || req.Subscription is null) { return(new RetrieveUpcomingInvoiceResponse { Invoice = upcomingInvoice, }); } else { var currentPeriodEnd = subscription.CurrentPeriodEnd; long immediateTotal = 0; long nextInvoiceSum = 0; foreach (var lineItem in upcomingInvoice.Lines.Data) { if (lineItem.Period.End == currentPeriodEnd) { immediateTotal += lineItem.Amount; } else { nextInvoiceSum += lineItem.Amount; } } return(new RetrieveUpcomingInvoiceResponse { ImmediateTotal = immediateTotal, NextInvoiceSum = nextInvoiceSum, Invoice = upcomingInvoice, }); } }
public InvoicesController() : base() { entityService = new InvoiceService(base.db); }
private string ProcessCaptureRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var apiKey = settings[settings["mode"] + "_secret_key"]; var billingMode = settings["billing_mode"]; ConfigureStripe(apiKey); ValidateBillingModeSetting(billingMode); var customerService = new CustomerService(); var subscriptionService = new SubscriptionService(); var invoiceService = new InvoiceService(); // Create the stripe customer var customer = customerService.Create(new CustomerCreateOptions { PaymentMethodId = billingMode == "charge" ? request.Form["stripePaymentMethodId"] : null, Email = order.PaymentInformation.Email, Metadata = new Dictionary <string, string> { { "customerId", order.CustomerId } } }); // Create subscription for customer (will auto attempt payment) var subscriptionOptions = new SubscriptionCreateOptions { CustomerId = customer.Id, Items = order.OrderLines.Select(x => new SubscriptionItemOption { PlanId = !string.IsNullOrWhiteSpace(x.Properties["planId"]) ? x.Properties["planId"] : x.Sku, Quantity = (long)x.Quantity }).ToList(), TaxPercent = order.VatRate.Value * 100, Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } }, Expand = new[] { "latest_invoice.payment_intent" }.ToList() }; if (billingMode == "charge") { subscriptionOptions.CollectionMethod = "charge_automatically"; subscriptionOptions.DefaultPaymentMethodId = request.Form["stripePaymentMethodId"]; } else { subscriptionOptions.CollectionMethod = "send_invoice"; subscriptionOptions.DaysUntilDue = settings.ContainsKey("invoice_days_until_due") ? int.Parse("0" + settings["invoice_days_until_due"]) : 30; } foreach (var prop in order.Properties) { subscriptionOptions.Metadata.Add(prop.Alias, prop.Value); } var subscription = subscriptionService.Create(subscriptionOptions); var invoice = subscription.LatestInvoice; // Stash the stripe info in the order order.Properties.AddOrUpdate(new CustomProperty("stripeCustomerId", customer.Id) { ServerSideOnly = true }); order.Properties.AddOrUpdate(new CustomProperty("stripeSubscriptionId", subscription.Id) { ServerSideOnly = true }); order.Save(); if (subscription.Status == "active" || subscription.Status == "trialing") { return(JsonConvert.SerializeObject(new { success = true })); } else if (invoice.PaymentIntent.Status == "requires_action") { return(JsonConvert.SerializeObject(new { requires_action = true, payment_intent_client_secret = invoice.PaymentIntent.ClientSecret })); } return(JsonConvert.SerializeObject(new { error = "Invalid payment intent status" })); }
private void generateInvoiceBtn_Click(object sender, EventArgs e) { if (appointment == null || displayedAppointment == null) { return; } var invoicePatient = patientService.GetPatientById(appointment.patient_id); var invoiceService = serviceService.GetServiceById(appointment.service_id); serviceCost = invoiceService.cost; var prescriptions = prescriptionService.GetPatientPrescriptionByPatientId(invoicePatient.patient_id); List <string> drugNames = new List <string>(); foreach (var prescription in prescriptions) { drugNames.Add(drugService.GetDrugById(prescription.drug_id).drug_name); drugCost += drugService.GetDrugById(prescription.drug_id).cost; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(); foreach (var drugName in drugNames) { stringBuilder.AppendLine(drugName); } var invoiceTotalCost = drugCost + serviceCost; InvoiceService invoiceDAOService = new InvoiceService(); invoice = new Invoice.Invoice() { patient_id = invoicePatient.patient_id, invoice_date = appointment.appointment_date, service_id = invoiceService.service_id, drug_names = stringBuilder.ToString(), total_cost = invoiceTotalCost }; var created = invoiceDAOService.CreateInvoice(invoice); MessageBox.Show(created ? "Invoice Successfully Generated!" : "Failed to Generate Invoice"); if (!created) { return; } printPreviewDialog1.StartPosition = FormStartPosition.CenterScreen; printPreviewDialog1.Size = new Size(480, 600); ToolStripButton b = new ToolStripButton(); b.Image = Properties.Resources.PrintIcon; b.DisplayStyle = ToolStripItemDisplayStyle.Image; b.Click += printPreview_PrintClick; ((ToolStrip)(printPreviewDialog1.Controls[1])).Items.RemoveAt(0); ((ToolStrip)(printPreviewDialog1.Controls[1])).Items.Insert(0, b); printPreviewDialog1.ShowDialog(); }
protected override void Initialize() { _invoiceService = new InvoiceService(new MockUnitOfWorkProvider(), new RepositoryFactory()); _invoice = _invoiceService.CreateInvoice(_customer, _invoiceStatus, "test111", "name", "address1", "address2", "city", "state", "98225", "US", "*****@*****.**", string.Empty, string.Empty); Before = null; After = null; _beforeInvoice = null; _afterInvoice = null; _statusBefore = false; _statusAfter = false; _customer = MockCustomerDataMaker.CustomerForInserting().MockSavedWithKey(111); _invoiceStatus = MockInvoiceStatusDataMaker.InvoiceStatusUnpaidMock(); _anonymous = MockAnonymousCustomerDataMaker.AnonymousCustomerForInserting().MockSavedWithKey(Guid.NewGuid()); InvoiceService.Saving += delegate(IInvoiceService sender, SaveEventArgs <IInvoice> args) { BeforeTriggered = true; Before = args.SavedEntities.FirstOrDefault(); }; InvoiceService.Saved += delegate(IInvoiceService sender, SaveEventArgs <IInvoice> args) { AfterTriggered = true; After = args.SavedEntities.FirstOrDefault(); }; InvoiceService.Created += delegate(IInvoiceService sender, Core.Events.NewEventArgs <IInvoice> args) { AfterTriggered = true; After = args.Entity; }; InvoiceService.Deleting += delegate(IInvoiceService sender, DeleteEventArgs <IInvoice> args) { BeforeTriggered = true; Before = args.DeletedEntities.FirstOrDefault(); }; InvoiceService.Deleted += delegate(IInvoiceService sender, DeleteEventArgs <IInvoice> args) { AfterTriggered = true; After = args.DeletedEntities.FirstOrDefault(); }; InvoiceService.StatusChanging += delegate(IInvoiceService sender, StatusChangeEventArgs <IInvoice> args) { _statusBefore = true; _beforeInvoice = args.StatusChangedEntities; }; InvoiceService.StatusChanged += delegate(IInvoiceService sender, StatusChangeEventArgs <IInvoice> args) { _statusAfter = true; _afterInvoice = args.StatusChangedEntities; }; // General tests MockDatabaseUnitOfWork.Committed += delegate { CommitCalled = true; }; }