Exemplo n.º 1
0
        /// <summary>
        /// 获取扫码支付的Html
        /// </summary>
        /// <param name="transaction">支付交易</param>
        /// <returns></returns>
        public virtual HtmlString GetQRCodePaymentHtml(PaymentTransaction transaction)
        {
            var templateManager = Application.Ioc.Resolve <TemplateManager>();

#if !NETCORE
            // 获取商户Id等设置
            var apiData = transaction.Api.ExtraData.GetOrDefault <ApiData>("ApiData") ?? new ApiData();
            // 获取货币信息,目前仅支持人民币支付
            var currencyManager = Application.Ioc.Resolve <CurrencyManager>();
            var info            = currencyManager.GetCurrency(transaction.CurrencyType);
            if (info == null || info.Type != "CNY")
            {
                return(new HtmlString(templateManager.RenderTemplate(
                                          "finance.payment/error_text.html",
                                          new { error = new T("Alipay only support CNY") })));
            }
            // 如果交易之前没有获取过二维码Url,则通过支付宝Api获取二维码Url
            // 当前沙箱环境中交易流水号相同时不会重复创建支付宝交易,仅可能会返回不同的二维码
            // 如果正式环境有变化可能需要做出更多处理,例如缓存之前的二维码(并考虑二维码的过期时间)
            var client  = GetAopClient(apiData);
            var request = new AlipayTradePrecreateRequest();
            request.BizContent = JsonConvert.SerializeObject(new {
                out_trade_no = transaction.Serial,                             // 交易流水号
                seller_id    = apiData.PayeePartnerId,                         // 收款商户Id
                total_amount = transaction.Amount.ToString("0.00"),            // 金额
                subject      = transaction.Description.TruncateWithSuffix(15), // 交易标题
                body         = transaction.Description,                        // 交易描述
            }, Formatting.Indented);
            var notifyUrl = PaymentUtils.GetReturnOrNotifyUrl(
                apiData.ReturnDomain, AlipayQRCodePayNotifyUrl);
            request.SetNotifyUrl(notifyUrl);
            var response = client.Execute(request);
            if (response.IsError)
            {
                return(new HtmlString(templateManager.RenderTemplate(
                                          "finance.payment/error_text.html",
                                          new { error = $"{response.Msg}: {response.SubMsg}" })));
            }
            // 生成二维码图片
            var generator    = new QRCodeGenerator();
            var qrCodeData   = generator.CreateQrCode(response.QrCode, QRCodeGenerator.ECCLevel.Q);
            var qrCode       = new Base64QRCode(qrCodeData);
            var qrCodeBase64 = qrCode.GetGraphic(20);
            // 返回模板
            return(new HtmlString(templateManager.RenderTemplate(
                                      "finance.payment.alipaymobile/qrcode_pay.html",
                                      new { transactionId = transaction.Id, qrCodeBase64 })));
#else
            return(new HtmlString(templateManager.RenderTemplate(
                                      "finance.payment/error_text.html",
                                      new { error = new T("Alipay qrcode pay is unsupported on .net core yet") })));
#endif
        }
Exemplo n.º 2
0
 /// <summary>
 /// 初始化
 /// </summary>
 /// <param name="apiData">接口数据</param>
 public WxPayConfig(WechatApiHandler.ApiData apiData)
 {
     APPID            = apiData.AppId;
     MCHID            = apiData.PartnerId;
     KEY              = apiData.PartnerKey;
     APPSECRET        = null;
     SSLCERT_PATH     = null;
     SSLCERT_PASSWORD = null;
     NOTIFY_URL       = PaymentUtils.GetReturnOrNotifyUrl(
         apiData.ReturnDomain, WeChatQRCodePayNotifyUrl);
     var ipAddress = NetworkUtils.GetClientIpAddress();
 }
Exemplo n.º 3
0
        /// <summary>
        /// 获取支付凭据
        /// </summary>
        /// <param name="transactionId">交易Id</param>
        /// <param name="paymentChannel">支付渠道</param>
        /// <param name="userAgent">客户端的UserAgent</param>
        /// <param name="ipAddress">客户端的Ip地址</param>
        /// <param name="charge">返回的支付凭据</param>
        /// <param name="realResultUrl">返回的结果Url</param
        /// <param name="waitResultUrl">等待返回的结果Url</param>>
        public virtual void GetCharge(
            Guid transactionId, string paymentChannel, string userAgent, string ipAddress,
            out Charge charge, out string realResultUrl, out string waitResultUrl)
        {
            var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>();
            PaymentTransaction transaction;
            PaymentApi         api;
            ApiData            apiData;

            using (UnitOfWork.Scope()) {
                // 获取交易和支付接口
                transaction = transactionManager.Get(transactionId);
                api         = transaction == null ? null : transaction.Api;
                // 检查交易和接口是否存在
                if (transaction == null)
                {
                    throw new BadRequestException(new T("Payment transaction not found"));
                }
                else if (api == null)
                {
                    throw new BadRequestException(new T("Payment api not exist"));
                }
                // 检查当前登录用户是否可以支付
                var result = transaction.Check(c => c.IsPayerLoggedIn);
                if (!result.First)
                {
                    throw new BadRequestException(result.Second);
                }
                result = transaction.Check(c => c.IsPayable);
                if (!result.First)
                {
                    throw new BadRequestException(result.Second);
                }
                apiData = transaction.Api.ExtraData.GetOrDefault <ApiData>("ApiData") ?? new ApiData();
            }
            // 检查货币,虽然Ping++有提供货币参数但是支付渠道里面都只能支付人民币
            if (transaction.CurrencyType != "CNY")
            {
                throw new BadRequestException(new T("Ping++ only support cny payment"));
            }
            // 获取Ping++的支付凭据
            // 注意这里非线程安全,如果添加多个Ping++接口可能会出问题
            Pingpp.SetApiKey(apiData.TradeSecretKey);
            Pingpp.SetPrivateKey(apiData.PartnerRsaPrivateKey);
            var configManager   = Application.Ioc.Resolve <GenericConfigManager>();
            var websiteSettings = configManager.GetData <WebsiteSettings>();
            var extra           = new Dictionary <string, object>();

            realResultUrl = PaymentUtils.GetReturnOrNotifyUrl(
                apiData.ReturnDomain,
                transactionManager.GetResultUrl(transactionId));
            waitResultUrl = PaymentUtils.GetReturnOrNotifyUrl(
                apiData.ReturnDomain,
                GetWaitResultUrl(transactionId));
            if (paymentChannel == "alipay_wap" ||
                paymentChannel == "alipay_pc_direct")
            {
                // 支付宝支付
                extra["success_url"] = waitResultUrl;
            }
            else if (paymentChannel == "bfb_wap")
            {
                // 百度钱包支付
                extra["result_url"] = waitResultUrl;
                extra["bfb_login"]  = apiData.BfbRequireLogin;
            }
            else if (paymentChannel == "upacp_wap" ||
                     paymentChannel == "upacp_pc")
            {
                // 银联支付
                extra["result_url"] = waitResultUrl;
            }
            else if (paymentChannel == "wx" ||
                     paymentChannel == "wx_pub" ||
                     paymentChannel == "wx_pub_qr" ||
                     paymentChannel == "wx_wap")
            {
                // 微信支付
                if (apiData.WeChatNoCredit)
                {
                    extra["limit_pay"] = "no_credit";
                }
                if (paymentChannel == "wx_pub")
                {
                    extra["open_id"] = apiData.WeChatOpenId;
                }
                else if (paymentChannel == "wx_pub_qr")
                {
                    extra["product_id"] = transaction.ExtraData
                                          .GetOrDefault <string>("WeChatProductId") ?? "0";
                }
                else if (paymentChannel == "wx_wap")
                {
                    extra["result_url"] = waitResultUrl;
                }
            }
            else if (paymentChannel == "jdpay_wap")
            {
                // 京东支付
                extra["success_url"] = waitResultUrl;
                extra["fail_url"]    = realResultUrl;
            }
            else if (paymentChannel == "fqlpay_wap")
            {
                // 分期乐支付
                extra["c_merch_id"] = apiData.FqlChildMerchantId;
                extra["return_url"] = waitResultUrl;
            }
            else if (paymentChannel == "qgbc_wap")
            {
                // 量化派支付
                extra["phone"] = transaction.ExtraData
                                 .GetOrDefault <string>("QgbcBuyerMobile") ?? "0";
                extra["return_url"] = waitResultUrl;
            }
            else if (paymentChannel == "qpay")
            {
                // QQ钱包
                var isIOS = userAgent.Contains("iphone") || userAgent.Contains("ipad");
                extra["device"] = isIOS ? "ios" : "android";
            }
            var chargeParams = new Dictionary <string, object>
            {
                { "order_no", transaction.Serial },
                { "amount", checked ((int)(transaction.Amount * 100)) },
                { "channel", paymentChannel },
                { "currency", "cny" },
                { "subject", $"{new T(websiteSettings.WebsiteName)} {transaction.Serial}" },
                { "body", transaction.Description },
                { "client_ip", ipAddress },
                { "app", new Dictionary <string, string> {
                      { "id", apiData.PingppAppId }
                  } },
                { "extra", extra }
            };

            charge = Charge.Create(chargeParams);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 获取支付Html
        /// </summary>
        /// <param name="transaction">支付交易</param>
        /// <returns></returns>
        public virtual HtmlString GetPaymentHtml(PaymentTransaction transaction)
        {
            var templateManager = Application.Ioc.Resolve <TemplateManager>();

#if !NETCORE
            // 获取商户Id等设置
            var apiData = transaction.Api.ExtraData.GetOrDefault <ApiData>("ApiData") ?? new ApiData();
            // 获取即时和异步返回地址
            var transactionManager = Application.Ioc.Resolve <PaymentTransactionManager>();
            var returnUrl          = PaymentUtils.GetReturnOrNotifyUrl(apiData.ReturnDomain, AlipayReturnUrl);
            var notifyUrl          = PaymentUtils.GetReturnOrNotifyUrl(apiData.ReturnDomain, AlipayNotifyUrl);
            // 获取货币信息,目前仅支持人民币支付
            var currencyManager = Application.Ioc.Resolve <CurrencyManager>();
            var info            = currencyManager.GetCurrency(transaction.CurrencyType);
            if (info == null || info.Type != "CNY")
            {
                return(new HtmlString(templateManager.RenderTemplate(
                                          "finance.payment/error_text.html",
                                          new { error = new T("Alipay only support CNY") })));
            }
            // 设置参数
            // 这里没有设置的参数有
            // anti_phishing_key 防钓鱼时间戳 目前不支持
            // exter_invoke_ip 客户端的IP地址 目前不支持, 防止多IP的用户不能使用
            // receive_name, receive_address, receive_zip, receive_phone, receive_mobile 目前不支持
            var parameters = new SortedDictionary <string, string>();
            parameters["partner"]           = apiData.PartnerId;                              // 商户Id
            parameters["seller_id"]         = apiData.PayeePartnerId;                         // 收款支付宝账号, 一般情况下收款账号就是签约账号
            parameters["_input_charset"]    = Config.input_charset;;                          // 请求编码,默认是utf-8
            parameters["payment_type"]      = Config.payment_type;                            // 支付类型,必须是1
            parameters["notify_url"]        = notifyUrl;                                      // 异步通知url
            parameters["return_url"]        = returnUrl;                                      // 同步返回url
            parameters["anti_phishing_key"] = Config.anti_phishing_key;                       // 防钓鱼时间戳, 目前不使用
            parameters["exter_invoke_ip"]   = Config.exter_invoke_ip;                         // 客户端的IP地址, 目前不使用
            parameters["out_trade_no"]      = transaction.Serial;                             // 交易流水号
            parameters["subject"]           = transaction.Description.TruncateWithSuffix(15); // 交易标题
            parameters["body"]     = transaction.Description;                                 // 交易描述
            parameters["show_url"] = new Uri(returnUrl).GetLeftPart(UriPartial.Authority);    // 商品展示地址,这里使用网站首页
            if (apiData.ServiceType == (int)AlipayServiceTypes.ImmediateArrival)
            {
                // 即时到账
                parameters["service"]   = "create_direct_pay_by_user";               // 服务类型 即时到账
                parameters["total_fee"] = transaction.Amount.ToString("0.00");       // 金额
            }
            else if (apiData.ServiceType == (int)AlipayServiceTypes.SecuredTransaction ||
                     apiData.ServiceType == (int)AlipayServiceTypes.DualInterface)
            {
                // 担保交易或双接口
                if (apiData.ServiceType == (int)AlipayServiceTypes.SecuredTransaction)
                {
                    parameters["service"] = "create_partner_trade_by_buyer";                     // 服务类型 担保交易
                }
                else
                {
                    parameters["service"] = "trade_create_by_buyer";                   // 服务类型 双接口
                }
                parameters["price"]             = transaction.Amount.ToString("0.00"); // 金额
                parameters["quantity"]          = "1";                                 // 商品数量,支付宝推荐为1
                parameters["logistics_fee"]     = "0";                                 // 物流费用,这套系统不支持单独传入物流费用
                parameters["logistics_type"]    = "EXPRESS";                           // 快递(可选EXPRESS, POST, EMS)
                parameters["logistics_payment"] = "SELLER_PAY";                        // 因为物流费用不单独算,只能用卖家承担运费
            }
            else if (apiData.ServiceType == (int)AlipayServiceTypes.WapPay)
            {
                // 手机支付
                parameters["service"]   = "alipay.wap.create.direct.pay.by.user";              // 服务类型 手机支付
                parameters["total_fee"] = transaction.Amount.ToString("0.00");                 // 金额
            }
            // 创建并返回支付Html
            var submit = new Submit(apiData.PartnerId, apiData.PartnerKey);
            var html   = submit.BuildRequest(parameters, "get", "submit");
            return(new HtmlString(html));
#else
            return(new HtmlString(templateManager.RenderTemplate(
                                      "finance.payment/error_text.html",
                                      new { error = new T("Alipay is unsupported on .net core yet") })));
#endif
        }