/// <summary> /// 刷卡支付 /// </summary> /// <param name="authCode">扫码设备获取到的微信用户刷卡授权码</param> /// <returns></returns> public ActionResult MicroPay(string authCode) { RequestHandler payHandler = new RequestHandler(null); var sp_billno = SystemTime.Now.ToString("HHmmss") + TenPayV3Util.BuildRandomStr(28); var nonceStr = TenPayV3Util.GetNoncestr(); payHandler.SetParameter("auth_code", authCode); //授权码 payHandler.SetParameter("body", "test"); //商品描述 payHandler.SetParameter("total_fee", "1"); //总金额 payHandler.SetParameter("out_trade_no", sp_billno); //产生随机的商户订单号 payHandler.SetParameter("spbill_create_ip", HttpContext.UserHostAddress()?.ToString()); //终端ip payHandler.SetParameter("appid", TenPayV3Info.AppId); //公众账号ID payHandler.SetParameter("mch_id", TenPayV3Info.MchId); //商户号 payHandler.SetParameter("nonce_str", nonceStr); //随机字符串 string sign = payHandler.CreateMd5Sign("key", TenPayV3Info.Key); payHandler.SetParameter("sign", sign);//签名 var result = TenPayOldV3.MicroPay(payHandler.ParseXML()); //此处只是完成最简单的支付功能,实际情况还需要考虑各种出错的情况,并处理错误,最后返回结果通知用户。 return(Content(result)); }
/// <summary> /// 原生支付 模式一 /// </summary> /// <returns></returns> public ActionResult Native() { try { RequestHandler nativeHandler = new RequestHandler(null); string timeStamp = TenPayV3Util.GetTimestamp(); string nonceStr = TenPayV3Util.GetNoncestr(); //商品Id,用户自行定义 string productId = SystemTime.Now.ToString("yyyyMMddHHmmss"); nativeHandler.SetParameter("appid", TenPayV3Info.AppId); nativeHandler.SetParameter("mch_id", TenPayV3Info.MchId); nativeHandler.SetParameter("time_stamp", timeStamp); nativeHandler.SetParameter("nonce_str", nonceStr); nativeHandler.SetParameter("product_id", productId); string sign = nativeHandler.CreateMd5Sign("key", TenPayV3Info.Key); var url = TenPayOldV3.NativePay(TenPayV3Info.AppId, timeStamp, TenPayV3Info.MchId, nonceStr, productId, sign); BitMatrix bitMatrix; bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 600, 600); var bw = new ZXing.BarcodeWriterPixelData(); var pixelData = bw.Write(bitMatrix); var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); var fileStream = new MemoryStream(); var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); try { // we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(_fileStream, System.Drawing.Imaging.ImageFormat.Png); _fileStream.Seek(0, SeekOrigin.Begin); return(File(_fileStream, "image/png")); } catch (Exception ex) { SenparcTrace.SendCustomLog("TenPayV3.Native 执行出错", ex.Message); SenparcTrace.BaseExceptionLog(ex); throw; } }
/// <summary> /// 下载对账单 /// </summary> /// <param name="date">日期,格式如:20170716</param> /// <returns></returns> public ActionResult DownloadBill(string date) { if (!Request.IsLocal()) { return(Content("出于安全考虑,此操作限定在本机上操作(实际项目可以添加登录权限限制后远程操作)!")); } string nonceStr = TenPayV3Util.GetNoncestr(); TenPayV3DownloadBillRequestData data = new TenPayV3DownloadBillRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, nonceStr, null, date, "ALL", TenPayV3Info.Key, null); var result = TenPayOldV3.DownloadBill(data); return(Content(result)); }
/// <summary> /// 关闭订单接口 /// </summary> /// <returns></returns> public ActionResult CloseOrder() { string nonceStr = TenPayV3Util.GetNoncestr(); RequestHandler packageReqHandler = new RequestHandler(null); //设置package订单参数 packageReqHandler.SetParameter("appid", TenPayV3Info.AppId); //公众账号ID packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId); //商户号 packageReqHandler.SetParameter("out_trade_no", ""); //填入商家订单号 packageReqHandler.SetParameter("nonce_str", nonceStr); //随机字符串 string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); packageReqHandler.SetParameter("sign", sign); //签名 string data = packageReqHandler.ParseXML(); var result = TenPayOldV3.CloseOrder(data); var res = XDocument.Parse(result); string openid = res.Element("xml").Element("openid").Value; return(Content(openid)); }
/// <summary> /// 退款申请接口 /// </summary> /// <returns></returns> public ActionResult Refund() { try { WeixinTrace.SendCustomLog("进入退款流程", "1"); string nonceStr = TenPayV3Util.GetNoncestr(); string outTradeNo = HttpContext.Session.GetString("BillNo"); WeixinTrace.SendCustomLog("进入退款流程", "2 outTradeNo:" + outTradeNo); string outRefundNo = "OutRefunNo-" + SystemTime.Now.Ticks; int totalFee = int.Parse(HttpContext.Session.GetString("BillFee")); int refundFee = totalFee; string opUserId = TenPayV3Info.MchId; var notifyUrl = "https://sdk.weixin.senparc.com/TenPayV3/RefundNotifyUrl"; var dataInfo = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key, null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl); #region 旧方法 //var cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";//根据自己的证书位置修改 //var password = TenPayV3Info.MchId;//默认为商户号,建议修改 //var result = TenPayOldV3.Refund(dataInfo, cert, password); #endregion #region 新方法(Senparc.Weixin v6.4.4+) var result = TenPayOldV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录 #endregion WeixinTrace.SendCustomLog("进入退款流程", "3 Result:" + result.ToJson()); ViewData["Message"] = $"退款结果:{result.result_code} {result.err_code_des}。您可以刷新当前页面查看最新结果。"; return(View()); //return Json(result, JsonRequestBehavior.AllowGet); } catch (Exception ex) { WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex)); throw; } #region 原始方法 //RequestHandler packageReqHandler = new RequestHandler(null); //设置package订单参数 //packageReqHandler.SetParameter("appid", TenPayV3Info.AppId); //公众账号ID //packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId); //商户号 //packageReqHandler.SetParameter("out_trade_no", "124138540220170502163706139412"); //填入商家订单号 ////packageReqHandler.SetParameter("out_refund_no", ""); //填入退款订单号 //packageReqHandler.SetParameter("total_fee", ""); //填入总金额 //packageReqHandler.SetParameter("refund_fee", "100"); //填入退款金额 //packageReqHandler.SetParameter("op_user_id", TenPayV3Info.MchId); //操作员Id,默认就是商户号 //packageReqHandler.SetParameter("nonce_str", nonceStr); //随机字符串 //string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); //packageReqHandler.SetParameter("sign", sign); //签名 ////退款需要post的数据 //string data = packageReqHandler.ParseXML(); ////退款接口地址 //string url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; ////本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中) //string cert = @"D:\cert\apiclient_cert_SenparcRobot.p12"; ////私钥(在安装证书时设置) //string password = TenPayV3Info.MchId; //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); ////调用证书 //X509Certificate2 cer = new X509Certificate2(cert, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet); //#region 发起post请求 //HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url); //webrequest.ClientCertificates.Add(cer); //webrequest.Method = "post"; //byte[] postdatabyte = Encoding.UTF8.GetBytes(data); //webrequest.ContentLength = postdatabyte.Length; //Stream stream; //stream = webrequest.GetRequestStream(); //stream.Write(postdatabyte, 0, postdatabyte.Length); //stream.Close(); //HttpWebResponse httpWebResponse = (HttpWebResponse)webrequest.GetResponse(); //StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream()); //string responseContent = streamReader.ReadToEnd(); //#endregion //// var res = XDocument.Parse(responseContent); ////string openid = res.Element("xml").Element("out_refund_no").Value; //return Content("申请成功:<br>" + HttpUtility.RequestUtility.HtmlEncode(responseContent)); #endregion }
/// <summary> /// 原生支付 模式二 /// 根据统一订单返回的code_url生成支付二维码。该模式链接较短,生成的二维码打印到结账小票上的识别率较高。 /// 注意:code_url有效期为2小时,过期后扫码不能再发起支付 /// </summary> /// <returns></returns> public ActionResult NativeByCodeUrl() { //创建支付应答对象 //RequestHandler packageReqHandler = new RequestHandler(null); var sp_billno = SystemTime.Now.ToString("HHmmss") + TenPayV3Util.BuildRandomStr(26); var nonceStr = TenPayV3Util.GetNoncestr(); //商品Id,用户自行定义 string productId = SystemTime.Now.ToString("yyyyMMddHHmmss"); //创建请求统一订单接口参数 //packageReqHandler.SetParameter("appid", TenPayV3Info.AppId); //packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId); //packageReqHandler.SetParameter("nonce_str", nonceStr); //packageReqHandler.SetParameter("body", "test"); //packageReqHandler.SetParameter("out_trade_no", sp_billno); //packageReqHandler.SetParameter("total_fee", "1"); //packageReqHandler.SetParameter("spbill_create_ip", HttpContext.UserHostAddress()?.ToString()); //packageReqHandler.SetParameter("notify_url", TenPayV3Info.TenPayV3Notify); //packageReqHandler.SetParameter("trade_type", TenPayV3Type.NATIVE.ToString()); //packageReqHandler.SetParameter("product_id", productId); //string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); //packageReqHandler.SetParameter("sign", sign); //string data = packageReqHandler.ParseXML(); var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, "test", sp_billno, 1, HttpContext.UserHostAddress()?.ToString(), TenPayV3Info.TenPayV3Notify, TenPay.TenPayV3Type.NATIVE, null, TenPayV3Info.Key, nonceStr, productId: productId); //调用统一订单接口 var result = TenPayOldV3.Unifiedorder(xmlDataInfo); //var unifiedorderRes = XDocument.Parse(result); //string codeUrl = unifiedorderRes.Element("xml").Element("code_url").Value; string codeUrl = result.code_url; BitMatrix bitMatrix; bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 600, 600); var bw = new ZXing.BarcodeWriterPixelData(); var pixelData = bw.Write(bitMatrix); using (var bitmap = new System.Drawing.Bitmap(pixelData.Width, pixelData.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb)) { using (var ms = new MemoryStream()) { var bitmapData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, pixelData.Width, pixelData.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb); try { // we assume that the row stride of the bitmap is aligned to 4 byte multiplied by the width of the image System.Runtime.InteropServices.Marshal.Copy(pixelData.Pixels, 0, bitmapData.Scan0, pixelData.Pixels.Length); } finally { bitmap.UnlockBits(bitmapData); } bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png); return(File(ms, "image/png")); } } }
public ActionResult NativeNotifyUrl() { ResponseHandler resHandler = new ResponseHandler(null); //返回给微信的请求 RequestHandler res = new RequestHandler(null); string openId = resHandler.GetParameter("openid"); string productId = resHandler.GetParameter("product_id"); if (openId == null || productId == null) { res.SetParameter("return_code", "FAIL"); res.SetParameter("return_msg", "回调数据异常"); } //创建支付应答对象 //RequestHandler packageReqHandler = new RequestHandler(null); var sp_billno = SystemTime.Now.ToString("HHmmss") + TenPayV3Util.BuildRandomStr(26);//最多32位 var nonceStr = TenPayV3Util.GetNoncestr(); //创建请求统一订单接口参数 //packageReqHandler.SetParameter("appid", TenPayV3Info.AppId); //packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId); //packageReqHandler.SetParameter("nonce_str", nonceStr); //packageReqHandler.SetParameter("body", "test"); //packageReqHandler.SetParameter("out_trade_no", sp_billno); //packageReqHandler.SetParameter("total_fee", "1"); //packageReqHandler.SetParameter("spbill_create_ip", HttpContext.UserHostAddress()?.ToString()); //packageReqHandler.SetParameter("notify_url", TenPayV3Info.TenPayV3Notify); //packageReqHandler.SetParameter("trade_type", TenPayV3Type.NATIVE.ToString()); //packageReqHandler.SetParameter("openid", openId); //packageReqHandler.SetParameter("product_id", productId); //string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key); //packageReqHandler.SetParameter("sign", sign); //string data = packageReqHandler.ParseXML(); var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, "test", sp_billno, 1, HttpContext.UserHostAddress()?.ToString(), TenPayV3Info.TenPayV3Notify, TenPay.TenPayV3Type.JSAPI, openId, TenPayV3Info.Key, nonceStr); try { //调用统一订单接口 var result = TenPayOldV3.Unifiedorder(xmlDataInfo); //var unifiedorderRes = XDocument.Parse(result); //string prepayId = unifiedorderRes.Element("xml").Element("prepay_id").Value; //创建应答信息返回给微信 res.SetParameter("return_code", result.return_code); res.SetParameter("return_msg", result.return_msg ?? "OK"); res.SetParameter("appid", result.appid); res.SetParameter("mch_id", result.mch_id); res.SetParameter("nonce_str", result.nonce_str); res.SetParameter("prepay_id", result.prepay_id); res.SetParameter("result_code", result.result_code); res.SetParameter("err_code_des", "OK"); string nativeReqSign = res.CreateMd5Sign("key", TenPayV3Info.Key); res.SetParameter("sign", nativeReqSign); } catch (Exception) { res.SetParameter("return_code", "FAIL"); res.SetParameter("return_msg", "统一下单失败"); } return(Content(res.ParseXML())); }
public ActionResult JsApi(int productId, int hc) { try { //获取产品信息 var products = ProductModel.GetFakeProductList(); var product = products.FirstOrDefault(z => z.Id == productId); if (product == null || product.GetHashCode() != hc) { return(Content("商品信息不存在,或非法进入!1002")); } //var openId = User.Identity.Name; var openId = HttpContext.Session.GetString("OpenId"); string sp_billno = Request.Query["order_no"]; if (string.IsNullOrEmpty(sp_billno)) { //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一 sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId /*10位*/, SystemTime.Now.ToString("yyyyMMddHHmmss"), TenPayV3Util.BuildRandomStr(6)); //注意:以上订单号仅作为演示使用,如果访问量比较大,建议增加订单流水号的去重检查。 } else { sp_billno = Request.Query["order_no"]; } var timeStamp = TenPayV3Util.GetTimestamp(); var nonceStr = TenPayV3Util.GetNoncestr(); var body = product == null ? "test" : product.Name; var price = product == null ? 100 : (int)(product.Price * 100);//单位:分 var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, price, HttpContext.UserHostAddress()?.ToString(), TenPayV3Info.TenPayV3Notify, TenPay.TenPayV3Type.JSAPI, openId, TenPayV3Info.Key, nonceStr); var result = TenPayOldV3.Unifiedorder(xmlDataInfo); //调用统一订单接口 //JsSdkUiPackage jsPackage = new JsSdkUiPackage(TenPayV3Info.AppId, timeStamp, nonceStr,); var package = string.Format("prepay_id={0}", result.prepay_id); ViewData["product"] = product; ViewData["appId"] = TenPayV3Info.AppId; ViewData["timeStamp"] = timeStamp; ViewData["nonceStr"] = nonceStr; ViewData["package"] = package; ViewData["paySign"] = TenPayOldV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key); //临时记录订单信息,留给退款申请接口测试使用 HttpContext.Session.SetString("BillNo", sp_billno); HttpContext.Session.SetString("BillFee", price.ToString()); return(View()); } catch (Exception ex) { var msg = ex.Message; msg += "<br>" + ex.StackTrace; msg += "<br>==Source==<br>" + ex.Source; if (ex.InnerException != null) { msg += "<br>===InnerException===<br>" + ex.InnerException.Message; } return(Content(msg)); } }
/// <summary> /// H5支付 /// </summary> /// <param name="productId"></param> /// <param name="hc"></param> /// <returns></returns> public ActionResult H5Pay(int productId, int hc) { { try { //获取产品信息 var products = ProductModel.GetFakeProductList(); var product = products.FirstOrDefault(z => z.Id == productId); if (product == null || product.GetHashCode() != hc) { return(Content("商品信息不存在,或非法进入!1002")); } string openId = null;//此时在外部浏览器,无法或得到OpenId string sp_billno = Request.Query["order_no"]; if (string.IsNullOrEmpty(sp_billno)) { //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一 sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId /*10位*/, SystemTime.Now.ToString("yyyyMMddHHmmss"), TenPayV3Util.BuildRandomStr(6)); } else { sp_billno = Request.Query["order_no"]; } var timeStamp = TenPayV3Util.GetTimestamp(); var nonceStr = TenPayV3Util.GetNoncestr(); var body = product == null ? "test" : product.Name; var price = product == null ? 100 : (int)(product.Price * 100); //var ip = Request.Params["REMOTE_ADDR"]; var xmlDataInfo = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, price, HttpContext.UserHostAddress()?.ToString(), TenPayV3Info.TenPayV3Notify, TenPay.TenPayV3Type.MWEB /*此处无论传什么,方法内部都会强制变为MWEB*/, openId, TenPayV3Info.Key, nonceStr); SenparcTrace.SendCustomLog("H5Pay接口请求", xmlDataInfo.ToJson()); var result = TenPayOldV3.Html5Order(xmlDataInfo); //调用统一订单接口 //JsSdkUiPackage jsPackage = new JsSdkUiPackage(TenPayV3Info.AppId, timeStamp, nonceStr,); /* * result:{"device_info":"","trade_type":"MWEB","prepay_id":"wx20170810143223420ae5b0dd0537136306","code_url":"","mweb_url":"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20170810143223420ae5b0dd0537136306\u0026package=1505175207","appid":"wx669ef95216eef885","mch_id":"1241385402","sub_appid":"","sub_mch_id":"","nonce_str":"juTchIZyhXvZ2Rfy","sign":"5A37D55A897C854F64CCCC4C94CDAFE3","result_code":"SUCCESS","err_code":"","err_code_des":"","return_code":"SUCCESS","return_msg":null} */ //return Json(result, JsonRequestBehavior.AllowGet); SenparcTrace.SendCustomLog("H5Pay接口返回", result.ToJson()); var package = string.Format("prepay_id={0}", result.prepay_id); ViewData["product"] = product; ViewData["appId"] = TenPayV3Info.AppId; ViewData["timeStamp"] = timeStamp; ViewData["nonceStr"] = nonceStr; ViewData["package"] = package; ViewData["paySign"] = TenPayOldV3.GetJsPaySign(TenPayV3Info.AppId, timeStamp, nonceStr, package, TenPayV3Info.Key); //设置成功页面(也可以不设置,支付成功后默认返回来源地址) var returnUrl = string.Format("https://sdk.weixin.senparc.com/TenpayV3/H5PaySuccess?productId={0}&hc={1}", productId, hc); var mwebUrl = result.mweb_url; if (!string.IsNullOrEmpty(mwebUrl)) { mwebUrl += string.Format("&redirect_url={0}", returnUrl.AsUrlData()); } ViewData["MWebUrl"] = mwebUrl; //临时记录订单信息,留给退款申请接口测试使用 HttpContext.Session.SetString("BillNo", sp_billno); HttpContext.Session.SetString("BillFee", price.ToString()); return(View()); } catch (Exception ex) { var msg = ex.Message; msg += "<br>" + ex.StackTrace; msg += "<br>==Source==<br>" + ex.Source; if (ex.InnerException != null) { msg += "<br>===InnerException===<br>" + ex.InnerException.Message; } return(Content(msg)); } } }