public void SetBranding(UserAccount currentUser) { if (currentUser != null) { BrandingConfiguration brandingConfiguration = CompanyProfileServiceFacade.RetrieveBrandingConfigurationByHierarchy(new BrandingConfigurationHierarchy() { BranchId = currentUser.BranchId, ChannelId = currentUser.ChannelId, DivisionId = currentUser.DivisionId }); if (brandingConfiguration != null) { HttpContext.Current.Session[SessionHelper.BrandName] = brandingConfiguration.DisplayName; HttpContext.Current.Session[SessionHelper.StyleSheetTheme] = brandingConfiguration.Theme; HttpContext.Current.Session[SessionHelper.BrandNameShort] = brandingConfiguration.NameShort; HttpContext.Current.Session[SessionHelper.BrandNameDomain] = brandingConfiguration.Url; HttpContext.Current.Session[SessionHelper.BrandPhone] = brandingConfiguration.Phone; HttpContext.Current.Session[SessionHelper.CompanyCopyrightName] = brandingConfiguration.CopyrightName; HttpContext.Current.Session[SessionHelper.CompanyProfileId] = brandingConfiguration.CompanyProfileId; HttpContext.Current.Session[SessionHelper.BrandingConfiguration] = brandingConfiguration; HttpContext.Current.Session[SessionHelper.BrandNameCssFile] = brandingConfiguration.BrandNameCssFile; HttpContext.Current.Session[SessionHelper.BrandingConfiguration] = brandingConfiguration; } } }
/// <summary> /// Retrieves the portal branding. /// </summary> /// <returns>The portal branding information.</returns> public async Task <Models.BrandingConfiguration> RetrieveAsync() { //BrandingConfiguration portalBranding = await ApplicationDomain.CachingService // .FetchAsync<BrandingConfiguration>(PortalBrandingCacheKey).ConfigureAwait(false); //if (portalBranding == null) //{ CloudBlockBlob portalBrandingBlob = await GetPortalBrandingBlobAsync().ConfigureAwait(false); BrandingConfiguration portalBranding = new BrandingConfiguration(); if (await portalBrandingBlob.ExistsAsync().ConfigureAwait(false)) { portalBranding = JsonConvert.DeserializeObject <BrandingConfiguration>(await portalBrandingBlob.DownloadTextAsync().ConfigureAwait(false)); await NormalizeAsync(portalBranding).ConfigureAwait(false); } else { // portal branding has not been configured yet portalBranding.OrganizationName = Resources.DefaultOrganizationName; } // cache the portal branding //await ApplicationDomain.CachingService.StoreAsync( // PortalBrandingCacheKey, // portalBranding).ConfigureAwait(false); //} return(portalBranding); }
/// <summary> /// Retrieves the portal branding. /// </summary> /// <returns>The portal branding information.</returns> public async Task <BrandingConfiguration> RetrieveAsync() { var portalBranding = await this.ApplicationDomain.CachingService .FetchAsync <BrandingConfiguration>(PortalBranding.PortalBrandingCacheKey); if (portalBranding == null) { var portalBrandingBlob = await this.GetPortalBrandingBlobAsync(); portalBranding = new BrandingConfiguration(); if (await portalBrandingBlob.ExistsAsync()) { portalBranding = JsonConvert.DeserializeObject <BrandingConfiguration>(await portalBrandingBlob.DownloadTextAsync()); await this.NormalizeAsync(portalBranding); } else { // portal branding has not been configured yet portalBranding.OrganizationName = Resources.DefaultOrganizationName; } // cache the portal branding await this.ApplicationDomain.CachingService.StoreAsync <BrandingConfiguration>( PortalBranding.PortalBrandingCacheKey, portalBranding); } return(portalBranding); }
/// <summary> /// Purchases one or more partner offers. /// </summary> /// <param name="order">The order to execute.</param> /// <returns>A transaction result which summarizes its outcome.</returns> public async Task <TransactionResult> PurchaseAsync(OrderViewModel order) { // use the normalizer to validate the order. OrderNormalizer orderNormalizer = new OrderNormalizer(ApplicationDomain, order); order = await orderNormalizer.NormalizePurchaseSubscriptionOrderAsync().ConfigureAwait(false); // build the purchase line items. List <PurchaseLineItem> purchaseLineItems = new List <PurchaseLineItem>(); foreach (OrderSubscriptionItemViewModel orderItem in order.Subscriptions) { string offerId = orderItem.OfferId; int quantity = orderItem.Quantity; purchaseLineItems.Add(new PurchaseLineItem(offerId, quantity)); } // associate line items in order to partner offers. IEnumerable <PurchaseLineItemWithOffer> lineItemsWithOffers = await AssociateWithPartnerOffersAsync(purchaseLineItems).ConfigureAwait(false); ICollection <IBusinessTransaction> subTransactions = new List <IBusinessTransaction>(); // prepare payment authorization AuthorizePayment paymentAuthorization = new AuthorizePayment(PaymentGateway); subTransactions.Add(paymentAuthorization); BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); // build the Partner Center order and pass it to the place order transaction Order partnerCenterPurchaseOrder = BuildPartnerCenterOrder(lineItemsWithOffers, portalBranding.BillingCycle); PlaceOrder placeOrder = new PlaceOrder( ApplicationDomain.PartnerCenterClient.Customers.ById(CustomerId), partnerCenterPurchaseOrder); subTransactions.Add(placeOrder); // configure a transaction to save the new resulting subscriptions and purchases into persistence PersistNewlyPurchasedSubscriptions persistSubscriptionsAndPurchases = new PersistNewlyPurchasedSubscriptions( CustomerId, ApplicationDomain.CustomerSubscriptionsRepository, ApplicationDomain.CustomerPurchasesRepository, () => new Tuple <Order, IEnumerable <PurchaseLineItemWithOffer> >(placeOrder.Result, lineItemsWithOffers)); subTransactions.Add(persistSubscriptionsAndPurchases); // configure a capture payment transaction and let it read the auth code from the payment authorization output CapturePayment capturePayment = new CapturePayment(PaymentGateway, () => paymentAuthorization.Result); subTransactions.Add(capturePayment); // build an aggregated transaction from the previous steps and execute it as a whole await RunAggregatedTransaction(subTransactions).ConfigureAwait(false); return(new TransactionResult(persistSubscriptionsAndPurchases.Result, DateTime.UtcNow)); }
public GetStarted GetStarted(HttpContextBase httpContext, UserAccount user, Guid token, String username, bool isEmbedded, Int32?contactId = null, Guid?loanId = null, int?openInterviewPage = null, bool?isTempUser = false, Guid?parentLoanId = null, string sectionTitle = null) { StringBuilder sb = new StringBuilder(); sb.Append(GetChannelBorrowerSiteURL(user.UserAccountId)); sb.Append("LoanRequest.aspx?impersonateUser=1"); if (openInterviewPage.Equals(1)) { sb.Append("&openInterviewPage=1"); } sb.Append("&token="); sb.Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(token.ToString(), EncriptionKeys.Default))); sb.Append("&uname="); // username of new created account sb.Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(username, EncriptionKeys.Default))); sb.Append("&cuid="); // concierge Id sb.Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(user.UserAccountId.ToString(), EncriptionKeys.Default))); sb.Append("&chid="); BrandingConfiguration bc = (BrandingConfiguration)httpContext.Session[SessionHelper.BrandingConfiguration]; sb.Append(bc == null ? 0 : bc.ChannelId); if (contactId != null && contactId != -1) { sb.Append("&contactId="); // contact Id of the contact associated with new user account sb.Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(contactId.ToString(), EncriptionKeys.Default))); } if (loanId != null && loanId != Guid.Empty) { sb.Append("&lid="); sb.Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(loanId.ToString(), EncriptionKeys.Default))); } sb.Append("&isEmbedded="); sb.Append(isEmbedded ? "1" : "0"); sb.Append("&isTempUser="******"1" : "0"); sb.Append("&LoanCenter=1"); if (parentLoanId != null) { sb.Append("&plid=").Append(httpContext.Server.UrlEncode(EncryptionHelper.EncryptRijndael(parentLoanId.ToString(), EncriptionKeys.Default))); } return(new GetStarted() { BorrowerUrl = sb.ToString(), SectionTitle = !string.IsNullOrEmpty(sectionTitle) ? sectionTitle : "Start a Prospect/New Loan" }); }
/// <summary> /// Updates the portal branding. /// </summary> /// <param name="updatedBrandingConfiguration">The new portal branding.</param> /// <returns>The updated portal branding.</returns> public async Task <BrandingConfiguration> UpdateAsync(BrandingConfiguration updatedBrandingConfiguration) { updatedBrandingConfiguration.AssertNotNull(nameof(updatedBrandingConfiguration)); await this.NormalizeAsync(updatedBrandingConfiguration); var portalBrandingBlob = await this.GetPortalBrandingBlobAsync(); await portalBrandingBlob.UploadTextAsync(JsonConvert.SerializeObject(updatedBrandingConfiguration)); // invalidate the cache, we do not update it to avoid race condition between web instances await this.ApplicationDomain.CachingService.ClearAsync(PortalBranding.PortalBrandingCacheKey); return(updatedBrandingConfiguration); }
/// <summary> /// Updates the portal branding. /// </summary> /// <param name="updatedBrandingConfiguration">The new portal branding.</param> /// <returns>The updated portal branding.</returns> public async Task <BrandingConfiguration> UpdateAsync(BrandingConfiguration updatedBrandingConfiguration) { updatedBrandingConfiguration.AssertNotNull(nameof(updatedBrandingConfiguration)); await NormalizeAsync(updatedBrandingConfiguration).ConfigureAwait(false); CloudBlockBlob portalBrandingBlob = await GetPortalBrandingBlobAsync().ConfigureAwait(false); await portalBrandingBlob.UploadTextAsync(JsonConvert.SerializeObject(updatedBrandingConfiguration)).ConfigureAwait(false); // invalidate the cache, we do not update it to avoid race condition between web instances await ApplicationDomain.CachingService.ClearAsync(PortalBrandingCacheKey).ConfigureAwait(false); // re-initialize the telemetry service because the configuration might have changed. await ApplicationDomain.TelemetryService.InitializeAsync().ConfigureAwait(false); return(updatedBrandingConfiguration); }
public async Task <ActionResult> Home() { BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); if (portalBranding.HeaderImage != null) { ViewBag.HeaderImage = portalBranding.HeaderImage.ToString(); } if (portalBranding.PrivacyAgreement != null) { ViewBag.PrivacyAgreement = portalBranding.PrivacyAgreement.ToString(); } CustomerPortalPrincipal principal = HttpContext.User as CustomerPortalPrincipal; ViewBag.OrganizationName = portalBranding.OrganizationName; ViewBag.IsPortalAdmin = principal.IsPortalAdmin; return(PartialView()); }
public async Task <PaymentConfiguration> UpdatePaymentConfiguration(PaymentConfiguration paymentConfiguration) { // validate the payment configuration before saving. PayPalGateway.ValidateConfiguration(paymentConfiguration); // check if branding configuration has been setup else don't create web experience profile. bool isBrandingConfigured = await ApplicationDomain.Instance.PortalBranding.IsConfiguredAsync(); if (isBrandingConfigured) { // create a web experience profile using the branding for the web store. BrandingConfiguration brandConfig = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync(); paymentConfiguration.WebExperienceProfileId = PayPalGateway.CreateWebExperienceProfile(paymentConfiguration, brandConfig, ApplicationDomain.Instance.PortalLocalization.CountryIso2Code); } // Save the validated & complete payment configuration to repository. PaymentConfiguration paymentConfig = await ApplicationDomain.Instance.PaymentConfigurationRepository.UpdateAsync(paymentConfiguration); return(paymentConfig); }
public async Task <ActionResult> FrameworkFragments() { WebPortalConfigurationManager builder = ApplicationConfiguration.WebPortalConfigurationManager; ViewBag.Templates = (await builder.AggregateNonStartupAssets().ConfigureAwait(false)).Templates; BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); ViewBag.OrganizationName = portalBranding.OrganizationName; if (portalBranding.OrganizationLogo != null) { ViewBag.OrganizationLogo = portalBranding.OrganizationLogo.ToString(); } ViewBag.ContactUs = portalBranding.ContactUs; ViewBag.ContactSales = portalBranding.ContactSales; ViewBag.CurrencySymbol = ApplicationDomain.Instance.PortalLocalization.CurrencySymbol; return(PartialView()); }
protected void Application_PreRequestHandlerExecute(object sender, EventArgs e) { try { if (Context.Handler is IRequiresSessionState) { if (Session[SessionHelper.BrandName] == null || Session[SessionHelper.StyleSheetTheme] == null || Session[SessionHelper.BrandNameShort] == null || Session[SessionHelper.BrandNameDomain] == null || Session[SessionHelper.BrandPhone] == null || Session[SessionHelper.CompanyCopyrightName] == null || Session[SessionHelper.CompanyProfileId] == null) { BrandingConfiguration brandingConfiguration = CompanyProfileServiceFacade.RetrieveBrandingConfiguration(StringHelper.FixUrl(Context.Request.Url.Host)); if (brandingConfiguration != null) { Session[SessionHelper.BrandName] = brandingConfiguration.DisplayName; Session[SessionHelper.StyleSheetTheme] = brandingConfiguration.Theme; Session[SessionHelper.BrandNameShort] = brandingConfiguration.NameShort; Session[SessionHelper.BrandNameDomain] = brandingConfiguration.Url; Session[SessionHelper.BrandPhone] = brandingConfiguration.Phone; Session[SessionHelper.CompanyCopyrightName] = brandingConfiguration.CopyrightName; Session[SessionHelper.CompanyProfileId] = brandingConfiguration.CompanyProfileId; Session[SessionHelper.BrandingConfiguration] = brandingConfiguration; Session[SessionHelper.BrandNameCssFile] = brandingConfiguration.BrandNameCssFile; Session[SessionHelper.BrandingConfiguration] = brandingConfiguration; } } } // CDNHelper.SetCdnSettingInSession(); BundleConfig.RegisterBundles(BundleTable.Bundles); } catch (Exception ex) { TraceHelper.Error(TraceCategory.Global, "Error occurred in Global.asax.cs - Application_PreRequestHandlerExecute()!", ex, Guid.Empty, -1); } }
/// <summary> /// Gets the subscriptions managed by customers and partners /// </summary> /// <returns>returns managed subscriptions view model</returns> private async Task <ManagedSubscriptionsViewModel> GetManagedSubscriptions() { DateTime startTime = DateTime.Now; string clientCustomerId = Principal.PartnerCenterCustomerId; // responseCulture determines decimals, currency and such CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale); // localeSpecificApiClient allows pulling offer names localized to supported portal locales compatible with Offer API supported locales. IPartner localeSpecificPartnerCenterClient = ApplicationDomain.Instance.PartnerCenterClient.With(RequestContextFactory.Instance.Create(ApplicationDomain.Instance.PortalLocalization.OfferLocale)); // Get all subscriptions of customer from PC ResourceCollection <Subscription> customerAllSubscriptions = await localeSpecificPartnerCenterClient.Customers.ById(clientCustomerId).Subscriptions.GetAsync().ConfigureAwait(false); IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(clientCustomerId).ConfigureAwait(false); IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false); IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false); List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>(); // iterate through and build the list of customer's subscriptions. foreach (CustomerSubscriptionEntity subscription in customerSubscriptions) { PartnerOffer partnerOfferItem = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId); string subscriptionTitle = partnerOfferItem.Title; string portalOfferId = partnerOfferItem.Id; decimal portalOfferPrice = partnerOfferItem.Price; DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime(); int remainingDays = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days; bool isRenewable = remainingDays <= 30; // IsRenewable is true if subscription is going to expire in 30 days. bool isEditable = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; // IsEditable is true if today is lesser or equal to subscription expiry date. // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription. MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId); if (alignedMicrosoftOffer == null) { // The offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer. partnerOfferItem.IsInactive = true; isRenewable = false; isEditable = false; } BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); // Compute the pro rated price per seat for this subcription & return for client side processing during updates. decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice, portalBranding.BillingCycle), Resources.Culture.NumberFormat.CurrencyDecimalDigits); SubscriptionViewModel subscriptionItem = new SubscriptionViewModel() { SubscriptionId = subscription.SubscriptionId, FriendlyName = subscriptionTitle, PortalOfferId = portalOfferId, PortalOfferPrice = portalOfferPrice.ToString("C", responseCulture), IsRenewable = isRenewable, IsEditable = isEditable, SubscriptionExpiryDate = subscriptionExpiryDate.Date.ToString("d", responseCulture), SubscriptionProRatedPrice = proratedPerSeatPrice }; // add this subcription to the customer's subscription list. customerSubscriptionsView.Add(subscriptionItem); } List <CustomerSubscriptionModel> customerManagedSubscriptions = new List <CustomerSubscriptionModel>(); List <PartnerSubscriptionModel> partnerManagedSubscriptions = new List <PartnerSubscriptionModel>(); // Divide the subscriptions by customer and partner foreach (Subscription customerSubscriptionFromPC in customerAllSubscriptions.Items) { SubscriptionViewModel subscription = customerSubscriptionsView.FirstOrDefault(sub => sub.SubscriptionId == customerSubscriptionFromPC.Id); // Customer managed subscription found if (subscription != null) { CustomerSubscriptionModel customerSubscription = new CustomerSubscriptionModel() { SubscriptionId = customerSubscriptionFromPC.Id, LicensesTotal = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture), Status = GetStatusType(customerSubscriptionFromPC.Status), CreationDate = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture), FriendlyName = subscription.FriendlyName, IsRenewable = subscription.IsRenewable, IsEditable = subscription.IsEditable, PortalOfferId = subscription.PortalOfferId, SubscriptionProRatedPrice = subscription.SubscriptionProRatedPrice }; customerManagedSubscriptions.Add(customerSubscription); } else { PartnerSubscriptionModel partnerSubscription = new PartnerSubscriptionModel() { Id = customerSubscriptionFromPC.Id, OfferName = customerSubscriptionFromPC.OfferName, Quantity = customerSubscriptionFromPC.Quantity.ToString("G", responseCulture), Status = GetStatusType(customerSubscriptionFromPC.Status), CreationDate = customerSubscriptionFromPC.CreationDate.ToString("d", responseCulture), }; partnerManagedSubscriptions.Add(partnerSubscription); } } ManagedSubscriptionsViewModel managedSubscriptions = new ManagedSubscriptionsViewModel() { CustomerManagedSubscriptions = customerManagedSubscriptions.OrderByDescending(customerManagedSubscription => customerManagedSubscription.CreationDate), PartnerManagedSubscriptions = partnerManagedSubscriptions.OrderByDescending(partnerManagedSubscription => partnerManagedSubscription.CreationDate) }; // Capture the request for customer managed subscriptions and partner managed subscriptions for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", clientCustomerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "CustomerManagedSubscriptions", customerManagedSubscriptions.Count }, { "PartnerManagedSubscriptions", partnerManagedSubscriptions.Count } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetManagedSubscriptions", eventProperties, eventMetrics); return(managedSubscriptions); }
/// <summary> /// Applies business rules to <see cref="BrandingConfiguration"/> instances. /// </summary> /// <param name="brandingConfiguration">A branding configuration instance.</param> /// <returns>A task.</returns> private async Task NormalizeAsync(BrandingConfiguration brandingConfiguration) { brandingConfiguration.AssertNotNull(nameof(brandingConfiguration)); brandingConfiguration.OrganizationName.AssertNotEmpty("OrganizationName"); if (brandingConfiguration.ContactUs == null) { throw new PartnerDomainException(ErrorCode.InvalidInput, "ContactUs section not found in portal branding configuration").AddDetail("Field", "ContactUs"); } brandingConfiguration.ContactUs.Email.AssertNotEmpty("Email"); try { new MailAddress(brandingConfiguration.ContactUs.Email); } catch (FormatException) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid contact us email address").AddDetail("Field", "ContactUs.Email"); } try { brandingConfiguration.ContactUs.Phone.AssertNotEmpty("ContactUs.Phone"); } catch (ArgumentException) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid contact us phone").AddDetail("Field", "ContactUs.Phone"); } if (brandingConfiguration.ContactSales == null) { // default the contact sales to the contact us information brandingConfiguration.ContactSales = new ContactUsInformation() { Email = brandingConfiguration.ContactUs.Email, Phone = brandingConfiguration.ContactUs.Phone }; } else { if (string.IsNullOrWhiteSpace(brandingConfiguration.ContactSales.Email)) { brandingConfiguration.ContactSales.Email = brandingConfiguration.ContactUs.Email; } else { try { new MailAddress(brandingConfiguration.ContactSales.Email); } catch (FormatException) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid contact sales email address").AddDetail("Field", "ContactSales.Email"); } } if (string.IsNullOrWhiteSpace(brandingConfiguration.ContactSales.Phone)) { brandingConfiguration.ContactSales.Phone = brandingConfiguration.ContactUs.Phone; } else { try { brandingConfiguration.ContactSales.Phone.AssertNotEmpty("ContactSales.Phone"); } catch (ArgumentException) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid contact sales phone").AddDetail("Field", "ContactSales.Phone"); } } } if (brandingConfiguration.OrganizationLogoContent != null) { // there is an logo image specified, upload it to BLOB storage and setup the URI property to point to it brandingConfiguration.OrganizationLogo = await this.UploadStreamToBlobStorageAsync( "OrganizationLogo", brandingConfiguration.OrganizationLogoContent); brandingConfiguration.OrganizationLogoContent = null; } if (brandingConfiguration.HeaderImageContent != null) { // there is a header image specified, upload it to BLOB storage and setup the URI property to point to it brandingConfiguration.HeaderImage = await this.UploadStreamToBlobStorageAsync( "HeaderImage", brandingConfiguration.HeaderImageContent); brandingConfiguration.HeaderImageContent = null; } }
public async Task <BrandingConfiguration> UpdateBrandingConfiguration() { BrandingConfiguration brandingConfiguration = new BrandingConfiguration() { AgreementUserId = HttpContext.Current.Request.Form["AgreementUserId"], OrganizationName = HttpContext.Current.Request.Form["OrganizationName"], ContactUs = new ContactUsInformation() { Email = HttpContext.Current.Request.Form["ContactUsEmail"], Phone = HttpContext.Current.Request.Form["ContactUsPhone"], }, ContactSales = new ContactUsInformation() { Email = HttpContext.Current.Request.Form["ContactSalesEmail"], Phone = HttpContext.Current.Request.Form["ContactSalesPhone"], } }; string organizationLogo = HttpContext.Current.Request.Form["OrganizationLogo"]; HttpPostedFile organizationLogoPostedFile = HttpContext.Current.Request.Files["OrganizationLogoFile"]; if (organizationLogoPostedFile != null && Path.GetFileName(organizationLogoPostedFile.FileName) == organizationLogo) { // there is a new organization logo to be uploaded if (!organizationLogoPostedFile.ContentType.Trim().StartsWith("image/", StringComparison.InvariantCultureIgnoreCase)) { throw new PartnerDomainException(ErrorCode.InvalidFileType, Resources.InvalidOrganizationLogoFileTypeMessage).AddDetail("Field", "OrganizationLogoFile"); } brandingConfiguration.OrganizationLogoContent = organizationLogoPostedFile.InputStream; } else if (!string.IsNullOrWhiteSpace(organizationLogo)) { try { // the user either did not specify a logo or he did but changed the organization logo text to point to somewhere else i.e. a URI brandingConfiguration.OrganizationLogo = new Uri(organizationLogo, UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidOrganizationLogoUriMessage, invalidUri).AddDetail("Field", "OrganizationLogo"); } } string headerImage = HttpContext.Current.Request.Form["HeaderImage"]; HttpPostedFile headerImageUploadPostedFile = HttpContext.Current.Request.Files["HeaderImageFile"]; if (headerImageUploadPostedFile != null && Path.GetFileName(headerImageUploadPostedFile.FileName) == headerImage) { // there is a new header image to be uploaded if (!headerImageUploadPostedFile.ContentType.Trim().StartsWith("image/", StringComparison.InvariantCultureIgnoreCase)) { throw new PartnerDomainException(ErrorCode.InvalidFileType, Resources.InvalidHeaderImageMessage).AddDetail("Field", "HeaderImageFile"); } brandingConfiguration.HeaderImageContent = headerImageUploadPostedFile.InputStream; } else if (!string.IsNullOrWhiteSpace(headerImage)) { try { // the user either did not specify a header image or he did but changed the organization logo text to point to somewhere else i.e. a URI brandingConfiguration.HeaderImage = new Uri(headerImage, UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidHeaderImageUriMessage, invalidUri).AddDetail("Field", "HeaderImage"); } } if (!string.IsNullOrWhiteSpace(HttpContext.Current.Request.Form["PrivacyAgreement"])) { try { brandingConfiguration.PrivacyAgreement = new Uri(HttpContext.Current.Request.Form["PrivacyAgreement"], UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidPrivacyUriMessage, invalidUri).AddDetail("Field", "PrivacyAgreement"); } } if (!string.IsNullOrWhiteSpace(HttpContext.Current.Request.Form["InstrumentationKey"])) { brandingConfiguration.InstrumentationKey = HttpContext.Current.Request.Form["InstrumentationKey"]; } BrandingConfiguration updatedBrandingConfiguration = await ApplicationDomain.Instance.PortalBranding.UpdateAsync(brandingConfiguration).ConfigureAwait(false); bool isPaymentConfigurationSetup = await ApplicationDomain.Instance.PaymentConfigurationRepository.IsConfiguredAsync().ConfigureAwait(false); if (isPaymentConfigurationSetup) { // update the web experience profile. PaymentConfiguration paymentConfiguration = await ApplicationDomain.Instance.PaymentConfigurationRepository.RetrieveAsync().ConfigureAwait(false); paymentConfiguration.WebExperienceProfileId = PaymentGatewayConfig.GetPaymentGatewayInstance(ApplicationDomain.Instance, "retrieve payment").CreateWebExperienceProfile(paymentConfiguration, updatedBrandingConfiguration, ApplicationDomain.Instance.PortalLocalization.CountryIso2Code); await ApplicationDomain.Instance.PaymentConfigurationRepository.UpdateAsync(paymentConfiguration).ConfigureAwait(false); } return(updatedBrandingConfiguration); }
/// <summary> /// Creates Web Experience profile using portal branding and payment configuration. /// </summary> /// <param name="paymentConfig">The Payment configuration.</param> /// <param name="brandConfig">The branding configuration.</param> /// <param name="countryIso2Code">The locale code used by the web experience profile. Example-US.</param> /// <returns>The created web experience profile id.</returns> public string CreateWebExperienceProfile(PaymentConfiguration paymentConfig, BrandingConfiguration brandConfig, string countryIso2Code) { ////no need to implement this method return(string.Empty); }
/// <summary> /// Fetches all Microsoft CSP offers. /// </summary> /// <returns>A list of all Microsoft CSP offers.</returns> public async Task <IEnumerable <MicrosoftOffer> > RetrieveMicrosoftOffersAsync() { List <MicrosoftOffer> microsoftOffers = await ApplicationDomain.CachingService .FetchAsync <List <MicrosoftOffer> >(MicrosoftOffersCacheKey).ConfigureAwait(false); if (microsoftOffers == null) { // Need to manage this based on the offer locale supported by the Offer API. Either its english or using one of the supported offer locale to retrieve localized offers for the store front. IPartner localeSpecificPartnerCenterClient = ApplicationDomain.PartnerCenterClient.With(RequestContextFactory.Instance.Create(ApplicationDomain.PortalLocalization.OfferLocale)); // Offers.ByCountry is required to pull country / region specific offers. PartnerCenter.Models.ResourceCollection <PartnerCenter.Models.Offers.Offer> partnerCenterOffers = await localeSpecificPartnerCenterClient.Offers.ByCountry(ApplicationDomain.PortalLocalization.CountryIso2Code).GetAsync().ConfigureAwait(false); // Get the current billing cycle to filter down the eligible offers BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); PartnerCenter.Models.Offers.BillingCycleType offerBillingCycle = PartnerCenter.Models.Offers.BillingCycleType.Unknown; switch (portalBranding.BillingCycle) { case BillingCycleType.Annual: offerBillingCycle = PartnerCenter.Models.Offers.BillingCycleType.Monthly; break; case BillingCycleType.Monthly: offerBillingCycle = PartnerCenter.Models.Offers.BillingCycleType.Annual; break; default: throw new NotImplementedException($"Billing cycle {portalBranding.BillingCycle} is not implemented"); } // Get offers which support the desired billing cycle IEnumerable <PartnerCenter.Models.Offers.Offer> eligibleOffers = partnerCenterOffers?.Items.Where(offer => !offer.IsAddOn && (offer.PrerequisiteOffers == null || !offer.PrerequisiteOffers.Any()) && offer.IsAvailableForPurchase && offer.SupportedBillingCycles.Contains(offerBillingCycle)); microsoftOffers = new List <MicrosoftOffer>(); if (eligibleOffers != null) { foreach (PartnerCenter.Models.Offers.Offer partnerCenterOffer in eligibleOffers) { microsoftOffers.Add(new MicrosoftOffer() { Offer = partnerCenterOffer, ThumbnailUri = new Uri(await ApplicationDomain.MicrosoftOfferLogoIndexer.GetOfferLogoUriAsync(partnerCenterOffer).ConfigureAwait(false), UriKind.Relative) }); } } // cache the Microsoft offers for one day await ApplicationDomain.CachingService.StoreAsync( MicrosoftOffersCacheKey, microsoftOffers, TimeSpan.FromDays(1)).ConfigureAwait(false); } return(microsoftOffers); }
/// <summary> /// Creates Web Experience profile using portal branding and payment configuration. /// </summary> /// <param name="paymentConfig">The Payment configuration.</param> /// <param name="brandConfig">The branding configuration.</param> /// <param name="countryIso2Code">The locale code used by the web experience profile. Example-US.</param> /// <returns>The created web experience profile id.</returns> public string CreateWebExperienceProfile(PaymentConfiguration paymentConfig, BrandingConfiguration brandConfig, string countryIso2Code) { ////Payu does not provide the concept of webprofile ////stored authorization in WebExperienceProfileId return(paymentConfig.WebExperienceProfileId); }
/// <summary> /// Normalizes an order to add seats to a subscription. /// </summary> /// <returns>Normalized order.</returns> public async Task <OrderViewModel> NormalizePurchaseAdditionalSeatsOrderAsync() { OrderViewModel order = Order; order.CustomerId.AssertNotEmpty(nameof(order.CustomerId)); if (order.OperationType != CommerceOperationType.AdditionalSeatsPurchase) { throw new PartnerDomainException(ErrorCode.InvalidInput, Resources.InvalidOperationForOrderMessage).AddDetail("Field", "OperationType"); } // create result order object prefilling it with operation type & customer id. OrderViewModel orderResult = new OrderViewModel() { CustomerId = order.CustomerId, OrderId = order.OrderId, OperationType = order.OperationType }; order.Subscriptions.AssertNotNull(nameof(order.Subscriptions)); List <OrderSubscriptionItemViewModel> orderSubscriptions = order.Subscriptions.ToList(); if (orderSubscriptions.Count != 1) { throw new PartnerDomainException(ErrorCode.InvalidInput).AddDetail("ErrorMessage", Resources.MoreThanOneSubscriptionUpdateErrorMessage); } string subscriptionId = orderSubscriptions.First().SubscriptionId; int seatsToPurchase = orderSubscriptions.First().Quantity; subscriptionId.AssertNotEmpty(nameof(subscriptionId)); // is Required for the commerce operation. seatsToPurchase.AssertPositive("seatsToPurchase"); // grab the customer subscription from our store CustomerSubscriptionEntity subscriptionToAugment = await GetSubscriptionAsync(subscriptionId, order.CustomerId).ConfigureAwait(false); // retrieve the partner offer this subscription relates to, we need to know the current price PartnerOffer partnerOffer = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync(subscriptionToAugment.PartnerOfferId).ConfigureAwait(false); if (partnerOffer.IsInactive) { // renewing deleted offers is prohibited throw new PartnerDomainException(ErrorCode.PurchaseDeletedOfferNotAllowed).AddDetail("Id", partnerOffer.Id); } // retrieve the subscription from Partner Center Subscriptions.ISubscription subscriptionOperations = ApplicationDomain.Instance.PartnerCenterClient.Customers.ById(order.CustomerId).Subscriptions.ById(subscriptionId); // if subscription expiry date.Date is less than today's UTC date then subcription has expired. if (subscriptionToAugment.ExpiryDate.Date < DateTime.UtcNow.Date) { // this subscription has already expired, don't permit adding seats until the subscription is renewed throw new PartnerDomainException(ErrorCode.SubscriptionExpired); } BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); decimal proratedSeatCharge = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscriptionToAugment.ExpiryDate, partnerOffer.Price, portalBranding.BillingCycle), Resources.Culture.NumberFormat.CurrencyDecimalDigits); //decimal totalCharge = Math.Round(proratedSeatCharge * seatsToPurchase, Resources.Culture.NumberFormat.CurrencyDecimalDigits); List <OrderSubscriptionItemViewModel> resultOrderSubscriptions = new List <OrderSubscriptionItemViewModel> { new OrderSubscriptionItemViewModel() { OfferId = subscriptionId, SubscriptionId = subscriptionId, PartnerOfferId = subscriptionToAugment.PartnerOfferId, SubscriptionExpiryDate = subscriptionToAugment.ExpiryDate, Quantity = seatsToPurchase, SeatPrice = proratedSeatCharge, SubscriptionName = partnerOffer.Title } }; orderResult.Subscriptions = resultOrderSubscriptions; return(orderResult); }
/// <summary> /// Gets the summary of subscriptions for a portal customer. /// </summary> /// <param name="customerId">The customer Id.</param> /// <returns>Subscription Summary.</returns> private async Task <SubscriptionsSummary> GetSubscriptionSummaryAsync(string customerId) { DateTime startTime = DateTime.Now; IEnumerable <CustomerSubscriptionEntity> customerSubscriptions = await ApplicationDomain.Instance.CustomerSubscriptionsRepository.RetrieveAsync(customerId).ConfigureAwait(false); IEnumerable <CustomerPurchaseEntity> customerSubscriptionsHistory = await ApplicationDomain.Instance.CustomerPurchasesRepository.RetrieveAsync(customerId).ConfigureAwait(false); IEnumerable <PartnerOffer> allPartnerOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveAsync().ConfigureAwait(false); IEnumerable <MicrosoftOffer> currentMicrosoftOffers = await ApplicationDomain.Instance.OffersRepository.RetrieveMicrosoftOffersAsync().ConfigureAwait(false); // start building the summary. decimal summaryTotal = 0; // format all responses to client using portal locale. CultureInfo responseCulture = new CultureInfo(ApplicationDomain.Instance.PortalLocalization.Locale); List <SubscriptionViewModel> customerSubscriptionsView = new List <SubscriptionViewModel>(); // iterate through and build the list of customer's subscriptions. foreach (CustomerSubscriptionEntity subscription in customerSubscriptions) { decimal subscriptionTotal = 0; int licenseTotal = 0; List <SubscriptionHistory> historyItems = new List <SubscriptionHistory>(); // collect the list of history items for this subcription. IOrderedEnumerable <CustomerPurchaseEntity> subscriptionHistoryList = customerSubscriptionsHistory .Where(historyItem => historyItem.SubscriptionId == subscription.SubscriptionId) .OrderBy(historyItem => historyItem.TransactionDate); // iterate through and build the SubsriptionHistory for this subscription. foreach (CustomerPurchaseEntity historyItem in subscriptionHistoryList) { decimal orderTotal = Math.Round(historyItem.SeatPrice * historyItem.SeatsBought, responseCulture.NumberFormat.CurrencyDecimalDigits); historyItems.Add(new SubscriptionHistory() { OrderTotal = orderTotal.ToString("C", responseCulture), // Currency format. PricePerSeat = historyItem.SeatPrice.ToString("C", responseCulture), // Currency format. SeatsBought = historyItem.SeatsBought.ToString("G", responseCulture), // General format. OrderDate = historyItem.TransactionDate.ToLocalTime().ToString("d", responseCulture), // Short date format. OperationType = GetOperationType(historyItem.PurchaseType) // Localized Operation type string. }); // Increment the subscription total. licenseTotal += historyItem.SeatsBought; // Increment the subscription total. subscriptionTotal += orderTotal; } PartnerOffer partnerOfferItem = allPartnerOffers.FirstOrDefault(offer => offer.Id == subscription.PartnerOfferId); string subscriptionTitle = partnerOfferItem.Title; string portalOfferId = partnerOfferItem.Id; decimal portalOfferPrice = partnerOfferItem.Price; DateTime subscriptionExpiryDate = subscription.ExpiryDate.ToUniversalTime(); int remainingDays = (subscriptionExpiryDate.Date - DateTime.UtcNow.Date).Days; bool isRenewable = remainingDays <= 30; bool isEditable = DateTime.UtcNow.Date <= subscriptionExpiryDate.Date; // TODO :: Handle Microsoft offer being pulled back due to EOL. // Temporarily mark this partnerOffer item as inactive and dont allow store front customer to manage this subscription. MicrosoftOffer alignedMicrosoftOffer = currentMicrosoftOffers.FirstOrDefault(offer => offer.Offer.Id == partnerOfferItem.MicrosoftOfferId); if (alignedMicrosoftOffer == null) { partnerOfferItem.IsInactive = true; } if (partnerOfferItem.IsInactive) { // in case the offer is inactive (marked for deletion) then dont allow renewals or editing on this subscription tied to this offer. isRenewable = false; isEditable = false; } BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); // Compute the pro rated price per seat for this subcription & return for client side processing during updates. decimal proratedPerSeatPrice = Math.Round(CommerceOperations.CalculateProratedSeatCharge(subscription.ExpiryDate, portalOfferPrice, portalBranding.BillingCycle), Resources.Culture.NumberFormat.CurrencyDecimalDigits); SubscriptionViewModel subscriptionItem = new SubscriptionViewModel() { SubscriptionId = subscription.SubscriptionId, FriendlyName = subscriptionTitle, PortalOfferId = portalOfferId, PortalOfferPrice = portalOfferPrice.ToString("C", responseCulture), IsRenewable = isRenewable, // IsRenewable is true if subscription is going to expire in 30 days. IsEditable = isEditable, // IsEditable is true if today is lesser or equal to subscription expiry date. LicensesTotal = licenseTotal.ToString("G", responseCulture), // General format. SubscriptionTotal = subscriptionTotal.ToString("C", responseCulture), // Currency format. SubscriptionExpiryDate = subscriptionExpiryDate.Date.ToString("d", responseCulture), // Short date format. SubscriptionOrderHistory = historyItems, SubscriptionProRatedPrice = proratedPerSeatPrice }; // add this subcription to the customer's subscription list. customerSubscriptionsView.Add(subscriptionItem); // Increment the summary total. summaryTotal += subscriptionTotal; } // Capture the request for the customer summary for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", customerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }, { "NumberOfSubscriptions", customerSubscriptionsView.Count } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("GetSubscriptionSummaryAsync", eventProperties, eventMetrics); // Sort List of subscriptions based on portal offer name. return(new SubscriptionsSummary() { Subscriptions = customerSubscriptionsView.OrderBy(subscriptionItem => subscriptionItem.FriendlyName), SummaryTotal = summaryTotal.ToString("C", responseCulture) // Currency format. }); }
public async Task <SubscriptionsSummary> ProcessOrderForUnAuthenticatedCustomer(string customerId, string paymentId, string payerId) { DateTime startTime = DateTime.Now; customerId.AssertNotEmpty(nameof(customerId)); paymentId.AssertNotEmpty(nameof(paymentId)); payerId.AssertNotEmpty(nameof(payerId)); BrandingConfiguration branding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); CustomerViewModel customerRegistrationInfoPersisted = await ApplicationDomain.Instance.CustomerRegistrationRepository.RetrieveAsync(customerId).ConfigureAwait(false); Customer newCustomer = new Customer() { CompanyProfile = new CustomerCompanyProfile() { Domain = customerRegistrationInfoPersisted.DomainName, }, BillingProfile = new CustomerBillingProfile() { Culture = customerRegistrationInfoPersisted.BillingCulture, Language = customerRegistrationInfoPersisted.BillingLanguage, Email = customerRegistrationInfoPersisted.Email, CompanyName = customerRegistrationInfoPersisted.CompanyName, DefaultAddress = new Address() { FirstName = customerRegistrationInfoPersisted.FirstName, LastName = customerRegistrationInfoPersisted.LastName, AddressLine1 = customerRegistrationInfoPersisted.AddressLine1, AddressLine2 = customerRegistrationInfoPersisted.AddressLine2, City = customerRegistrationInfoPersisted.City, State = customerRegistrationInfoPersisted.State, Country = customerRegistrationInfoPersisted.Country, PostalCode = customerRegistrationInfoPersisted.ZipCode, PhoneNumber = customerRegistrationInfoPersisted.Phone, } } }; // Register customer newCustomer = await ApplicationDomain.Instance.PartnerCenterClient.Customers.CreateAsync(newCustomer).ConfigureAwait(false); ResourceCollection <AgreementMetaData> agreements = await ApplicationDomain.Instance.PartnerCenterClient.AgreementDetails.GetAsync().ConfigureAwait(false); // Obtain reference to the Microsoft Cloud Agreement. AgreementMetaData microsoftCloudAgreement = agreements.Items.FirstOrDefault(agr => agr.AgreementType == AgreementType.MicrosoftCloudAgreement); // Attest that the customer has accepted the Microsoft Cloud Agreement (MCA). await ApplicationDomain.Instance.PartnerCenterClient.Customers[newCustomer.Id].Agreements.CreateAsync( new Agreement { DateAgreed = DateTime.UtcNow, PrimaryContact = new PartnerCenter.Models.Agreements.Contact { Email = customerRegistrationInfoPersisted.Email, FirstName = customerRegistrationInfoPersisted.FirstName, LastName = customerRegistrationInfoPersisted.LastName, PhoneNumber = customerRegistrationInfoPersisted.Phone }, TemplateId = microsoftCloudAgreement.TemplateId, Type = AgreementType.MicrosoftCloudAgreement, UserId = branding.AgreementUserId }); string newCustomerId = newCustomer.CompanyProfile.TenantId; CustomerViewModel customerViewModel = new CustomerViewModel() { AddressLine1 = newCustomer.BillingProfile.DefaultAddress.AddressLine1, AddressLine2 = newCustomer.BillingProfile.DefaultAddress.AddressLine2, City = newCustomer.BillingProfile.DefaultAddress.City, State = newCustomer.BillingProfile.DefaultAddress.State, ZipCode = newCustomer.BillingProfile.DefaultAddress.PostalCode, Country = newCustomer.BillingProfile.DefaultAddress.Country, Phone = newCustomer.BillingProfile.DefaultAddress.PhoneNumber, Language = newCustomer.BillingProfile.Language, FirstName = newCustomer.BillingProfile.DefaultAddress.FirstName, LastName = newCustomer.BillingProfile.DefaultAddress.LastName, Email = newCustomer.BillingProfile.Email, CompanyName = newCustomer.BillingProfile.CompanyName, MicrosoftId = newCustomer.CompanyProfile.TenantId, UserName = newCustomer.BillingProfile.Email, Password = newCustomer.UserCredentials.Password, AdminUserAccount = newCustomer.UserCredentials.UserName + "@" + newCustomer.CompanyProfile.Domain }; IPaymentGateway paymentGateway = PaymentGatewayConfig.GetPaymentGatewayInstance(ApplicationDomain.Instance, "ProcessingOrder"); OrderViewModel orderToProcess = await paymentGateway.GetOrderDetailsFromPaymentAsync(payerId, paymentId, string.Empty, string.Empty).ConfigureAwait(false); // Assign the actual customer Id orderToProcess.CustomerId = newCustomerId; CommerceOperations commerceOperation = new CommerceOperations(ApplicationDomain.Instance, newCustomerId, paymentGateway); await commerceOperation.PurchaseAsync(orderToProcess).ConfigureAwait(false); SubscriptionsSummary summaryResult = await GetSubscriptionSummaryAsync(newCustomerId).ConfigureAwait(false); // Remove the persisted customer registration info. await ApplicationDomain.Instance.CustomerRegistrationRepository.DeleteAsync(customerId).ConfigureAwait(false); // Capture the request for the customer summary for analysis. Dictionary <string, string> eventProperties = new Dictionary <string, string> { { "CustomerId", orderToProcess.CustomerId } }; // Track the event measurements for analysis. Dictionary <string, double> eventMetrics = new Dictionary <string, double> { { "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds } }; ApplicationDomain.Instance.TelemetryService.Provider.TrackEvent("api/order/NewCustomerProcessOrder", eventProperties, eventMetrics); summaryResult.CustomerViewModel = customerViewModel; return(summaryResult); }
public async Task <BrandingConfiguration> UpdateBrandingConfiguration() { BrandingConfiguration brandingConfiguration = new BrandingConfiguration() { OrganizationName = HttpContext.Current.Request.Form["OrganizationName"], ContactUs = new ContactUsInformation() { Email = HttpContext.Current.Request.Form["ContactUsEmail"], Phone = HttpContext.Current.Request.Form["ContactUsPhone"], }, ContactSales = new ContactUsInformation() { Email = HttpContext.Current.Request.Form["ContactSalesEmail"], Phone = HttpContext.Current.Request.Form["ContactSalesPhone"], }, }; string organizationLogo = HttpContext.Current.Request.Form["OrganizationLogo"]; var organizationLogoPostedFile = HttpContext.Current.Request.Files["OrganizationLogoFile"]; if (organizationLogoPostedFile != null && Path.GetFileName(organizationLogoPostedFile.FileName) == organizationLogo) { // there is a new organization logo to be uploaded if (!organizationLogoPostedFile.ContentType.Trim().StartsWith("image/")) { throw new PartnerDomainException(ErrorCode.InvalidFileType, "Provide an image file type for the organization logo").AddDetail("Field", "OrganizationLogoFile"); } brandingConfiguration.OrganizationLogoContent = organizationLogoPostedFile.InputStream; } else if (!string.IsNullOrWhiteSpace(organizationLogo)) { try { // the user either did not specify a logo or he did but changed the organization logo text to point to somewhere else i.e. a URI brandingConfiguration.OrganizationLogo = new Uri(organizationLogo, UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid organization logo URI uploaded", invalidUri).AddDetail("Field", "OrganizationLogo"); } } string headerImage = HttpContext.Current.Request.Form["HeaderImage"]; var headerImageUploadPostedFile = HttpContext.Current.Request.Files["HeaderImageFile"]; if (headerImageUploadPostedFile != null && Path.GetFileName(headerImageUploadPostedFile.FileName) == headerImage) { // there is a new header image to be uploaded if (!headerImageUploadPostedFile.ContentType.Trim().StartsWith("image/")) { throw new PartnerDomainException(ErrorCode.InvalidFileType, "Provide an image file type for the header image").AddDetail("Field", "HeaderImageFile"); } brandingConfiguration.HeaderImageContent = headerImageUploadPostedFile.InputStream; } else if (!string.IsNullOrWhiteSpace(headerImage)) { try { // the user either did not specify a header image or he did but changed the organization logo text to point to somewhere else i.e. a URI brandingConfiguration.HeaderImage = new Uri(headerImage, UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid header image URI uploaded", invalidUri).AddDetail("Field", "HeaderImage"); } } if (!string.IsNullOrWhiteSpace(HttpContext.Current.Request.Form["PrivacyAgreement"])) { try { brandingConfiguration.PrivacyAgreement = new Uri(HttpContext.Current.Request.Form["PrivacyAgreement"], UriKind.Absolute); } catch (UriFormatException invalidUri) { throw new PartnerDomainException(ErrorCode.InvalidInput, "Invalid privacy agreement URI uploaded", invalidUri).AddDetail("Field", "PrivacyAgreement"); } } return(await ApplicationDomain.Instance.PortalBranding.UpdateAsync(brandingConfiguration)); }
/// <summary> /// Creates Web Experience profile using portal branding and payment configuration. /// </summary> /// <param name="paymentConfig">The Payment configuration.</param> /// <param name="brandConfig">The branding configuration.</param> /// <param name="countryIso2Code">The locale code used by the web experience profile. Example-US.</param> /// <returns>The created web experience profile id.</returns> public static string CreateWebExperienceProfile(PaymentConfiguration paymentConfig, BrandingConfiguration brandConfig, string countryIso2Code) { try { Dictionary <string, string> configMap = new Dictionary <string, string>(); configMap.Add("clientId", paymentConfig.ClientId); configMap.Add("clientSecret", paymentConfig.ClientSecret); configMap.Add("mode", paymentConfig.AccountType); configMap.Add("connectionTimeout", "120000"); string accessToken = new OAuthTokenCredential(configMap).GetAccessToken(); var apiContext = new APIContext(accessToken); apiContext.Config = configMap; // Pickup logo & brand name from branding configuration. // create the web experience profile. var profile = new WebProfile { name = Guid.NewGuid().ToString(), presentation = new Presentation { brand_name = brandConfig.OrganizationName, logo_image = brandConfig.HeaderImage?.ToString(), locale_code = countryIso2Code }, input_fields = new InputFields() { address_override = 1, allow_note = false, no_shipping = 1 }, flow_config = new FlowConfig() { landing_page_type = "billing" } }; var createdProfile = profile.Create(apiContext); // Now that new experience profile is created hence delete the older one. if (!string.IsNullOrWhiteSpace(paymentConfig.WebExperienceProfileId)) { try { WebProfile existingWebProfile = WebProfile.Get(apiContext, paymentConfig.WebExperienceProfileId); existingWebProfile.Delete(apiContext); } catch { } } return(createdProfile.id); } catch (PayPalException paypalException) { if (paypalException is IdentityException) { // thrown when API Context couldn't be setup. IdentityException identityFailure = paypalException as IdentityException; IdentityError failureDetails = identityFailure.Details; if (failureDetails != null && failureDetails.error.ToLower() == "invalid_client") { throw new PartnerDomainException(ErrorCode.PaymentGatewayIdentityFailureDuringConfiguration).AddDetail("ErrorMessage", Resources.PaymentGatewayIdentityFailureDuringConfiguration); } } // if this is not an identity exception rather some other issue. throw new PartnerDomainException(ErrorCode.PaymentGatewayFailure).AddDetail("ErrorMessage", paypalException.Message); } }
/// <summary> /// Renews an existing subscription for a customer. /// </summary> /// <param name="order">The order to execute.</param> /// <returns>A transaction result which summarizes its outcome.</returns> public async Task <TransactionResult> RenewSubscriptionAsync(OrderViewModel order) { // use the normalizer to validate the order. OrderNormalizer orderNormalizer = new OrderNormalizer(ApplicationDomain, order); order = await orderNormalizer.NormalizeRenewSubscriptionOrderAsync().ConfigureAwait(false); List <OrderSubscriptionItemViewModel> orderSubscriptions = order.Subscriptions.ToList(); string subscriptionId = orderSubscriptions.First().SubscriptionId; string partnerOfferId = orderSubscriptions.First().PartnerOfferId; decimal partnerOfferPrice = orderSubscriptions.First().SeatPrice; DateTime subscriptionExpiryDate = orderSubscriptions.First().SubscriptionExpiryDate; int quantity = orderSubscriptions.First().Quantity; decimal totalCharge = Math.Round(quantity * partnerOfferPrice, Resources.Culture.NumberFormat.CurrencyDecimalDigits); // retrieve the subscription from Partner Center Subscriptions.ISubscription subscriptionOperations = ApplicationDomain.PartnerCenterClient.Customers.ById(CustomerId).Subscriptions.ById(subscriptionId); PartnerCenter.Models.Subscriptions.Subscription partnerCenterSubscription = await subscriptionOperations.GetAsync().ConfigureAwait(false); // we will add up the transactions here ICollection <IBusinessTransaction> subTransactions = new List <IBusinessTransaction>(); // configure a transaction to charge the payment gateway with the prorated rate AuthorizePayment paymentAuthorization = new AuthorizePayment(PaymentGateway); subTransactions.Add(paymentAuthorization); // add a renew subscription transaction to the pipeline subTransactions.Add(new RenewSubscription( subscriptionOperations, partnerCenterSubscription)); DateTime rightNow = DateTime.UtcNow; // record the renewal in our purchase store subTransactions.Add(new RecordPurchase( ApplicationDomain.CustomerPurchasesRepository, new CustomerPurchaseEntity(CommerceOperationType.Renewal, Guid.NewGuid().ToString(), CustomerId, subscriptionId, partnerCenterSubscription.Quantity, partnerOfferPrice, rightNow))); DateTime expirationDate = subscriptionExpiryDate; BrandingConfiguration portalBranding = await ApplicationDomain.Instance.PortalBranding.RetrieveAsync().ConfigureAwait(false); switch (portalBranding.BillingCycle) { case BillingCycleType.Annual: expirationDate = expirationDate.AddYears(1); break; case BillingCycleType.Monthly: expirationDate = expirationDate.AddMonths(1); break; default: throw new NotImplementedException($"Billing cycle {portalBranding.BillingCycle} is not implemented"); } // extend the expiry date by one month or one year subTransactions.Add(new UpdatePersistedSubscription( ApplicationDomain.CustomerSubscriptionsRepository, new CustomerSubscriptionEntity(CustomerId, subscriptionId, partnerOfferId, expirationDate))); // add a capture payment to the transaction pipeline subTransactions.Add(new CapturePayment(PaymentGateway, () => paymentAuthorization.Result)); // run the pipeline await RunAggregatedTransaction(subTransactions).ConfigureAwait(false); TransactionResultLineItem renewSubscriptionResult = new TransactionResultLineItem( subscriptionId, partnerOfferId, partnerCenterSubscription.Quantity, partnerOfferPrice, totalCharge); return(new TransactionResult( new TransactionResultLineItem[] { renewSubscriptionResult }, rightNow)); }