예제 #1
0
        /// <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));
        }