public Task<DomainCard> AddAsync(DomainCardCreateOptions options)
        {
            return Task.Run(() =>
            {
                try
                {
                    StripeCardCreateOptions createOptions =
                        _mapper.Map<DomainCardCreateOptions, StripeCardCreateOptions>(options);

                    StripeCard card = _service.Create(options.CustomerId, createOptions);
                    return Task.FromResult(_mapper.Map<StripeCard, DomainCard>(card));
                }
                catch (StripeException e)
                {
                    throw new BillingException(string.Format("Failed to register card in billing system for customer {0}: {1}", options.CustomerId, e));
                }
            });
        }
        public async Task ChargeAsync(CompanyChargeOptions charge)
        {
            CompanyEntity company = await _companyRepository.GetAsync(charge.Id);
            if (company == null)
            {
                throw new NotFoundException(string.Format("Could not find company by id {0}", charge.Id));
            }

            if (company.State == (int)ResourceState.Blocked)
            {
                throw new ForbiddenException(string.Format("Company {0} is blocked", company.Id));
            }
            if (company.State == (int)ResourceState.Deleted)
            {
                throw new NotFoundException(string.Format("Company {0} is deleted", company.Id));
            }

            // Creating customer card
            var cardCreateOptions = new DomainCardCreateOptions
            {
                CustomerId = company.BillingCustomerId,
                TokenId = charge.TokenId
            };

            DomainCard billingCard;
            try
            {
                billingCard = await _billingCardService.AddAsync(cardCreateOptions);
            }
            catch (BillingException e)
            {
                throw new BadRequestException(string.Format("Failed to register card for company {0}: {1}", company.Id, e));
            }


            // Charging card
            var chargeCreateOptions = new DomainChargeCreateOptions
            {
                AmountInCents = charge.AmountInCents,
                CustomerId = company.BillingCustomerId,
                Currency = charge.Currency,
                Description = charge.Description,
                Card = billingCard.Id
            };

            // Balance will be updated automatically after callback (webhook) from billing system
            DomainCharge billingCharge;
            try
            {
                billingCharge = await _billingChargeService.AddAsync(chargeCreateOptions);
            }
            catch (BillingException e)
            {
                throw new BadRequestException(string.Format("Failed to charge billing customer {0} for company {1}: {2}", company.BillingCustomerId, company.Id, e));
            }

            if (!billingCharge.IsPaid)
            {
                // payment failed
                throw new PaymentRequiredException(string.Format("Payment failed for company {0}", company.Id));
            }
        }