/// <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"));
        }
예제 #2
0
 public DataServices(DbContext ctx)
 {
     DataContext = ctx as BizConnectEntities;
     Layouts = new LayoutService(DataContext);
     InvoiceData = new InvoiceDataService(DataContext);
     Client = new ClientService(DataContext);
     Invoice = new InvoiceService(DataContext);
 }
예제 #3
0
        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);
        }
예제 #5
0
        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));
            }

        }
예제 #6
0
 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);
 }
예제 #7
0
        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);
        }
예제 #8
0
 /// <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();
            }
        }
예제 #10
0
        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();
        }
예제 #12
0
        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));
        }
예제 #13
0
        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,
                            });
예제 #14
0
        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);
        }
예제 #15
0
 public InvoiceController()
 {
     invoiceService = new InvoiceService();
     commonService  = new CommonService();
 }
예제 #16
0
        /// <summary>
        /// Deletes all invoices
        /// </summary>
        public void DeleteAllInvoices()
        {
            var all = ((InvoiceService)InvoiceService).GetAll().ToArray();

            InvoiceService.Delete(all);
        }
예제 #17
0
        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);
        }
예제 #18
0
        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;
        }
예제 #19
0
        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");
            }
        }
예제 #20
0
        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"));
        }
예제 #21
0
        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;
 }
예제 #23
0
 public CountInvoiceController(TestContext testContext)
 {
     _invoiceService = new InvoiceService(testContext);
 }
예제 #24
0
        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);
        }
예제 #25
0
 public void Setup()
 {
     this.invoiceService = new InvoiceService();
 }
예제 #26
0
    // # 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);
    }
예제 #27
0
        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;
 }
예제 #32
0
        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" }));
        }
예제 #36
0
        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();
        }
예제 #37
0
        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;
            };
        }