/// <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)); }
/// <summary> /// Purchases one or more partner offers. /// </summary> /// <param name="purchaseLineItems">A collection of purchase lines items to buy.</param> /// <returns>A transaction result which summarizes its outcomes.</returns> public async Task <TransactionResult> PurchaseAsync(IEnumerable <PurchaseLineItem> purchaseLineItems) { purchaseLineItems.AssertNotNull(nameof(purchaseLineItems)); if (purchaseLineItems.Count() <= 0) { throw new ArgumentException("PurchaseLineItems should have at least one entry", nameof(purchaseLineItems)); } var lineItemsWithOffers = await this.AssociateWithPartnerOffersAsync(purchaseLineItems); ICollection <IBusinessTransaction> subTransactions = new List <IBusinessTransaction>(); decimal orderTotalPrice = Math.Round(this.CalculateOrderTotalPrice(lineItemsWithOffers), 2); // we have the order total, prepare payment authorization var paymentAuthorization = new AuthorizePayment(this.PaymentGateway, orderTotalPrice); subTransactions.Add(paymentAuthorization); // build the Partner Center order and pass it to the place order transaction Order partnerCenterPurchaseOrder = this.BuildPartnerCenterOrder(lineItemsWithOffers); var placeOrder = new PlaceOrder( this.ApplicationDomain.PartnerCenterClient.Customers.ById(this.CustomerId), partnerCenterPurchaseOrder); subTransactions.Add(placeOrder); // configure a transaction to save the new resulting subscriptions and purchases into persistence var persistSubscriptionsAndPurchases = new PersistNewlyPurchasedSubscriptions( this.CustomerId, this.ApplicationDomain.CustomerSubscriptionsRepository, this.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 var capturePayment = new CapturePayment(this.PaymentGateway, () => paymentAuthorization.Result); subTransactions.Add(capturePayment); // build an aggregated transaction from the previous steps and execute it as a whole await CommerceOperations.RunAggregatedTransaction(subTransactions); return(new TransactionResult(orderTotalPrice, persistSubscriptionsAndPurchases.Result, DateTime.UtcNow)); }