Exemplo n.º 1
0
        public Task <ApiResponse <SecurePayPayload> > SecurePayAsync(SecurePayRequest request)
        {
            if (request is null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return(PostAsync <ApiResponse <SecurePayPayload> >(Defaults.Api.Endpoints.SecurePayPath, request));
        }
        /// <summary>
        /// Post process payment (used by payment gateways that require redirecting to a third-party URL)
        /// </summary>
        /// <param name="postProcessPaymentRequest">Payment info required for an order processing</param>
        /// <returns>A task that represents the asynchronous operation</returns>
        public async Task PostProcessPaymentAsync(PostProcessPaymentRequest postProcessPaymentRequest)
        {
            if (postProcessPaymentRequest is null)
            {
                throw new ArgumentNullException(nameof(postProcessPaymentRequest));
            }

            var storeCurrency = await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId)
                                ?? throw new NopException("Primary store currency is not set");

            var order             = postProcessPaymentRequest.Order;
            var orderCustomValues = _paymentService.DeserializeCustomValues(order);

            var paymentChannelKey = await _localizationService.GetResourceAsync("Plugins.Payments.Yuansfer.PaymentChannel.Key");

            if (!orderCustomValues.TryGetValue(paymentChannelKey, out var vendor))
            {
                throw new NopException("The payment channel is not set");
            }

            var customer = await _workContext.GetCurrentCustomerAsync();

            var goods      = new List <object>();
            var orderItems = await _orderService.GetOrderItemsAsync(order.Id);

            foreach (var item in orderItems)
            {
                var product = await _productService.GetProductByIdAsync(item.ProductId)
                              ?? throw new InvalidOperationException("Cannot get the product.");

                var productName = string.Empty;
                if (string.IsNullOrEmpty(item.AttributesXml))
                {
                    productName = product.Name;
                }
                else
                {
                    var attributeInfo = await _productAttributeFormatter.FormatAttributesAsync(product, item.AttributesXml, customer, ", ");

                    productName = $"{product.Name} ({attributeInfo})";
                }

                goods.Add(new { goods_name = productName, quantity = item.Quantity.ToString() });
            }

            var currentRequestProtocol = _webHelper.GetCurrentRequestProtocol();
            var urlHelper   = _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext);
            var failUrl     = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, currentRequestProtocol);
            var callbackUrl = urlHelper.RouteUrl(Defaults.CheckoutCompletedRouteName, new { orderId = order.Id }, currentRequestProtocol);
            var ipnUrl      = urlHelper.RouteUrl(Defaults.SecurePayWebhookRouteName, null, currentRequestProtocol);

            var request = new SecurePayRequest
            {
                MerchantId     = _yuansferPaymentSettings.MerchantId,
                StoreId        = _yuansferPaymentSettings.StoreId,
                Vendor         = vendor.ToString(),
                Terminal       = "ONLINE",
                SettleCurrency = "USD",
                CallbackUrl    = callbackUrl,
                IpnUrl         = ipnUrl,
                GoodsInfo      = JsonConvert.SerializeObject(goods),
                Reference      = order.OrderGuid.ToString()
            };

            void redirectToErrorPage(string message)
            {
                _notificationService.ErrorNotification(message);

                var failUrl = urlHelper.RouteUrl(Defaults.OrderDetailsRouteName, new { orderId = order.Id }, currentRequestProtocol);

                _actionContextAccessor.ActionContext.HttpContext.Response.Redirect(failUrl);
            };

            var transactionAmount = decimal.Zero;

            var supportedVendorCurrencies = GetSupportedCurrenciesByVendor(request.Vendor);

            if (supportedVendorCurrencies.SupportedCurrencyCodes
                .Any(code => code.Equals(storeCurrency.CurrencyCode, StringComparison.InvariantCultureIgnoreCase)))
            {
                // primary store currency supported by vendor
                request.Currency  = storeCurrency.CurrencyCode;
                transactionAmount = order.OrderTotal;
            }
            else
            {
                // primary store currency not supported by vendor, then convert transaction amount to vendor currency
                var targetCurrency = await _currencyService.GetCurrencyByCodeAsync(supportedVendorCurrencies.PrimaryCurrencyCode);

                if (targetCurrency == null)
                {
                    throw new NopException($"Cannot convert order total to vendor currency. The currency by ISO code '{supportedVendorCurrencies.PrimaryCurrencyCode}' not found.");
                }

                request.Currency  = targetCurrency.CurrencyCode;
                transactionAmount = await _currencyService.ConvertCurrencyAsync(order.OrderTotal, storeCurrency, targetCurrency);
            }

            // validate amount for some vendors
            if (request.Vendor == "kakaopay" && transactionAmount < 50)
            {
                redirectToErrorPage("Total amount must be greater or equal to 50!");
                return;
            }
            else if (request.Vendor == "dana" && transactionAmount < 300)
            {
                redirectToErrorPage("Total amount must be greater or equal to 300!");
                return;
            }

            request.Amount = transactionAmount.ToString(CultureInfo.InvariantCulture);

            var signingParams = new[]