public async Task <ExecutePaymentResponse> ExecutePayment(ExecutePaymentDto input)
        {
            using (var paymentGatewayManager = _paymentGatewayManagerFactory.Create(input.Gateway))
            {
                var executePaymentResponse = await paymentGatewayManager.Object.ExecutePaymentAsync(input.AdditionalData);

                await _subscriptionPaymentRepository.UpdateByGatewayAndPaymentIdAsync(
                    input.Gateway,
                    executePaymentResponse.GetId(),
                    AbpSession.TenantId,
                    SubscriptionPaymentStatus.Completed
                    );

                var paymentId = executePaymentResponse.GetId();
                _paymentCache.AddCacheItem(new PaymentCacheItem(input.Gateway, input.PaymentPeriodType, paymentId));

                if (AbpSession.TenantId.HasValue)
                {
                    await TenantManager.UpdateTenantAsync(
                        AbpSession.GetTenantId(),
                        true,
                        false,
                        input.PaymentPeriodType,
                        input.EditionId,
                        input.EditionPaymentType
                        );
                }

                return(executePaymentResponse);
            }
        }
        private async Task Paid_Registratin_Should_Add_N_Days_To_SubscriptionEndDate(PaymentPeriodType paymentPeriodType)
        {
            //Arrange
            var utcNow        = Clock.Now.ToUniversalTime();
            var trialDayCount = 10;
            var edition       = new SubscribableEdition
            {
                DisplayName   = "Gold Edition",
                TrialDayCount = trialDayCount,
                MonthlyPrice  = 19,
                AnnualPrice   = 199
            };

            await UsingDbContextAsync(async context =>
            {
                context.SubscribableEditions.Add(edition);
                await context.SaveChangesAsync();
            });

            //Don't test payment here.
            _fakePaymentCache.AddCacheItem(new PaymentCacheItem(SubscriptionPaymentGatewayType.Paypal, paymentPeriodType, samplePaymentId));
            _subscriptionPaymentRepository.Insert(new SubscriptionPayment
            {
                PaymentPeriodType = paymentPeriodType,
                EditionId         = edition.Id,
                Amount            = edition.MonthlyPrice.Value,
                Gateway           = SubscriptionPaymentGatewayType.Paypal,
                PaymentId         = samplePaymentId,
                Status            = SubscriptionPaymentStatus.Completed,
            });

            var result = await _tenantRegistrationAppService.RegisterTenant(new RegisterTenantInput
            {
                EditionId         = edition.Id,
                AdminEmailAddress = "*****@*****.**",
                AdminPassword     = "******",
                Name = "Volosoft",
                SubscriptionStartType = SubscriptionStartType.Paid,
                TenancyName           = "Volosoft",
                Gateway   = SubscriptionPaymentGatewayType.Paypal,
                PaymentId = samplePaymentId
            });

            //Assert
            await UsingDbContextAsync(async context =>
            {
                var tenant = await context.Tenants.FirstOrDefaultAsync(t => t.Id == result.TenantId);
                tenant.ShouldNotBe(null);
                tenant.SubscriptionEndDateUtc.HasValue.ShouldBe(true);
                tenant.SubscriptionEndDateUtc.Value.Date.ShouldBe(utcNow.Date.AddDays((int)paymentPeriodType));
            });
        }
        private async Task <string> ExecutePaymentAsync(int editionId, PaymentPeriodType paymentPeriodType, SubscriptionPaymentGatewayType gateway)
        {
            var data = Request.Form.ToDictionary(q => q.Key, q => string.Join(",", q.Value));

            var result = await _paymentAppService.ExecutePayment(new ExecutePaymentDto
            {
                EditionId          = editionId,
                EditionPaymentType = EditionPaymentType.NewRegistration,
                Gateway            = gateway,
                AdditionalData     = data
            });

            var paymentId = result.GetId();

            _paymentCache.AddCacheItem(new PaymentCacheItem(gateway, paymentPeriodType, paymentId));

            return(paymentId);
        }