Beispiel #1
0
        /// <summary>
        /// Runs the specified argument.
        /// </summary>
        /// <param name="arg">The argument.</param>
        /// <param name="context">The context.</param>
        /// <returns>
        /// A cart with federate payment component
        /// </returns>
        public override async Task <CartEmailArgument> Run(CartEmailArgument arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires(arg).IsNotNull($"{this.Name}: The cart can not be null");

            var cart = arg.Cart;

            if (!cart.HasComponent <FederatedPaymentComponent>())
            {
                return(arg);
            }

            var payment = cart.GetComponent <FederatedPaymentComponent>();

            if (string.IsNullOrEmpty(payment.PaymentMethodNonce))
            {
                context.Abort(
                    await context.CommerceContext.AddMessage(
                        context.GetPolicy <KnownResultCodes>().Error,
                        "InvalidOrMissingPropertyValue",
                        new object[] { "PaymentMethodNonce" },
                        "Invalid or missing value for property 'PaymentMethodNonce'."),
                    context);
                return(arg);
            }

            var braintreeClientPolicy = context.GetPolicy <BraintreeClientPolicy>();

            if (string.IsNullOrEmpty(braintreeClientPolicy.Environment) || string.IsNullOrEmpty(braintreeClientPolicy.MerchantId) ||
                string.IsNullOrEmpty(braintreeClientPolicy.PublicKey) || string.IsNullOrEmpty(braintreeClientPolicy.PrivateKey))
            {
                await context.CommerceContext.AddMessage(
                    context.GetPolicy <KnownResultCodes>().Error,
                    "InvalidClientPolicy",
                    new object[] { "BraintreeClientPolicy" },
                    $"{this.Name}. Invalid BraintreeClientPolicy");

                return(arg);
            }

            try
            {
                var gateway = new BraintreeGateway(braintreeClientPolicy.Environment, braintreeClientPolicy.MerchantId, braintreeClientPolicy.PublicKey, braintreeClientPolicy.PrivateKey);

                var request = new TransactionRequest
                {
                    Amount             = payment.Amount.Amount,
                    PaymentMethodNonce = payment.PaymentMethodNonce,
                    BillingAddress     = ComponentsHelper.TranslatePartyToAddressRequest(payment.BillingParty, context),
                    Options            = new TransactionOptionsRequest
                    {
                        SubmitForSettlement = false
                    }
                };

                var result = gateway.Transaction.Sale(request);
                if (result.IsSuccess())
                {
                    var transaction = result.Target;
                    payment.TransactionId         = transaction?.Id;
                    payment.TransactionStatus     = transaction?.Status?.ToString();
                    payment.PaymentInstrumentType = transaction?.PaymentInstrumentType?.ToString();

                    var cc = transaction?.CreditCard;
                    payment.MaskedNumber = cc?.MaskedNumber;
                    payment.CardType     = cc?.CardType?.ToString();
                    if (cc?.ExpirationMonth != null)
                    {
                        payment.ExpiresMonth = int.Parse(cc.ExpirationMonth);
                    }

                    if (cc?.ExpirationYear != null)
                    {
                        payment.ExpiresYear = int.Parse(cc.ExpirationYear);
                    }
                }
                else
                {
                    var errorMessages = string.Concat(result.Message, " ", result.Errors.DeepAll().Aggregate(string.Empty, (current, error) => current + ("Error: " + (int)error.Code + " - " + error.Message + "\n")));
                    context.Abort(
                        await context.CommerceContext.AddMessage(
                            context.GetPolicy <KnownResultCodes>().Error,
                            "CreatePaymentFailed",
                            new object[] { "PaymentMethodNonce" },
                            $"{this.Name}. Create payment failed :{ errorMessages }"),
                        context);
                }

                return(arg);
            }
            catch (BraintreeException ex)
            {
                context.Abort(
                    await context.CommerceContext.AddMessage(
                        context.GetPolicy <KnownResultCodes>().Error,
                        "CreatePaymentFailed",
                        new object[] { "PaymentMethodNonce", ex },
                        $"{this.Name}. Create payment failed."),
                    context);
                return(arg);
            }
        }
        /// <summary>
        /// Runs the specified argument.
        /// </summary>
        /// <param name="arg">The argument.</param>
        /// <param name="context">The context.</param>
        /// <returns>
        /// A cart with federate payment component
        /// </returns>
        public override async Task <Order> Run(Order arg, CommercePipelineExecutionContext context)
        {
            Condition.Requires(arg).IsNotNull($"{this.Name}: order can not be null.");

            var order = arg;

            if (!order.HasComponent <OnHoldOrderComponent>())
            {
                var invalidOrderStateMessage = $"{this.Name}: Expected order in '{context.GetPolicy<KnownOrderStatusPolicy>().OnHold}' status but order was in '{order.Status}' status";
                context.Abort(
                    await context.CommerceContext.AddMessage(
                        context.GetPolicy <KnownResultCodes>().ValidationError,
                        "InvalidOrderState",
                        new object[] { context.GetPolicy <KnownOrderStatusPolicy>().OnHold, order.Status },
                        invalidOrderStateMessage).ConfigureAwait(false),
                    context);
            }

            var cart = context.CommerceContext.GetEntity <Cart>(c => c.Id.Equals(order.GetComponent <OnHoldOrderComponent>().TemporaryCart.EntityTarget, StringComparison.OrdinalIgnoreCase));

            if (cart == null || !cart.HasComponent <FederatedPaymentComponent>())
            {
                return(arg);
            }

            var payment = cart.GetComponent <FederatedPaymentComponent>();

            if (string.IsNullOrEmpty(payment.PaymentMethodNonce))
            {
                context.Abort(
                    await context.CommerceContext.AddMessage(
                        context.GetPolicy <KnownResultCodes>().Error,
                        "InvalidOrMissingPropertyValue",
                        new object[] { "PaymentMethodNonce" },
                        "Invalid or missing value for property 'PaymentMethodNonce'.").ConfigureAwait(false),
                    context);

                return(arg);
            }

            if (!string.IsNullOrEmpty(payment.TransactionId))
            {
                // Federated Payment was not changed
                return(arg);
            }

            var braintreeClientPolicy = context.GetPolicy <BraintreeClientPolicy>();

            if (!(await braintreeClientPolicy.IsValid(context.CommerceContext).ConfigureAwait(false)))
            {
                return(arg);
            }

            try
            {
                var gateway = new BraintreeGateway(braintreeClientPolicy?.Environment, braintreeClientPolicy?.MerchantId, braintreeClientPolicy?.PublicKey, braintreeClientPolicy?.PrivateKey);

                // void order payment
                if (order.HasComponent <FederatedPaymentComponent>())
                {
                    var orderPayment = order.GetComponent <FederatedPaymentComponent>();

                    // void order payment
                    var voidResult = gateway.Transaction.Void(orderPayment.TransactionId);
                    if (voidResult.IsSuccess())
                    {
                        context.Logger.LogInformation($"{this.Name} - Void Payment succeeded: {orderPayment.Id}");
                        orderPayment.TransactionStatus = voidResult.Target.Status.ToString();
                        await this.GenerateSalesActivity(order, orderPayment, context).ConfigureAwait(false);
                    }
                    else
                    {
                        var errorMessages = voidResult.Errors.DeepAll().Aggregate(string.Empty, (current, error) => current + ("Error: " + (int)error.Code + " - " + error.Message + "\n"));

                        context.Abort(
                            await context.CommerceContext.AddMessage(
                                context.GetPolicy <KnownResultCodes>().Error,
                                "PaymentVoidFailed",
                                new object[] { orderPayment.TransactionId },
                                $"{this.Name}. Payment void failed for transaction { orderPayment.TransactionId }: { errorMessages }").ConfigureAwait(false),
                            context);

                        return(arg);
                    }
                }

                var request = new TransactionRequest
                {
                    Amount             = payment.Amount.Amount,
                    PaymentMethodNonce = payment.PaymentMethodNonce,
                    BillingAddress     = ComponentsHelper.TranslatePartyToAddressRequest(payment.BillingParty),
                    Options            = new TransactionOptionsRequest
                    {
                        SubmitForSettlement = false
                    }
                };

                var result = gateway.Transaction.Sale(request);
                if (result.IsSuccess())
                {
                    var transaction = result.Target;
                    payment.TransactionId         = transaction?.Id;
                    payment.TransactionStatus     = transaction?.Status?.ToString();
                    payment.PaymentInstrumentType = transaction?.PaymentInstrumentType?.ToString();

                    var cc = transaction?.CreditCard;
                    payment.MaskedNumber = cc?.MaskedNumber;
                    payment.CardType     = cc?.CardType?.ToString();
                    if (cc?.ExpirationMonth != null)
                    {
                        payment.ExpiresMonth = int.Parse(cc.ExpirationMonth, System.Globalization.CultureInfo.InvariantCulture);
                    }

                    if (cc?.ExpirationYear != null)
                    {
                        payment.ExpiresYear = int.Parse(cc.ExpirationYear, System.Globalization.CultureInfo.InvariantCulture);
                    }
                }
                else
                {
                    var errorMessages = result.Errors.DeepAll().Aggregate(string.Empty, (current, error) => current + ("Error: " + (int)error.Code + " - " + error.Message + "\n"));

                    context.Abort(
                        await context.CommerceContext.AddMessage(
                            context.GetPolicy <KnownResultCodes>().Error,
                            "CreatePaymentFailed",
                            new object[] { "PaymentMethodNonce" },
                            $"{this.Name}. Create payment failed :{ errorMessages }").ConfigureAwait(false),
                        context);
                }

                return(arg);
            }
            catch (BraintreeException ex)
            {
                await context.CommerceContext.AddMessage(
                    context.GetPolicy <KnownResultCodes>().Error,
                    "InvalidClientPolicy",
                    new object[] { "BraintreeClientPolicy", ex },
                    $"{this.Name}. Invalid BraintreeClientPolicy").ConfigureAwait(false);

                return(arg);
            }
        }