微信支付----PC扫码支付(查询微信支付订单判断是否支付成功)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信支付----PC扫码支付(查询微信支付订单判断是否支付成功)相关的知识,希望对你有一定的参考价值。
c#webapi建议前端轮番查询订单状态 #region 查询扫码订单状态 /// <summary> /// 查询扫码支付状态 /// </summary> /// <param name="out_trade_no">支付订单号</param> /// <returns></returns> [HttpGet] public ResponseMessage PayMent_Result(string out_trade_no) { if (out_trade_no != null) { PayMent pay = new PayMent(); OrderDetail detail = pay.geidingdan(out_trade_no); if (detail.trade_state == "SUCCESS")//支付成功 { try { 自己的业务逻辑(数据库等等操作) } catch (Exception ex) { return new ResponseMessage { Code = -1};//系统异常 } return new ResponseMessage { Code = 1 }; } else if (detail.trade_state == "USERPAYING")//用户支付中 { return new ResponseMessage { Code = 3 }; //return "3"; } else if (detail.trade_state == "NOTPAY")//未支付 { return new ResponseMessage { Code = 2 }; // return "2"; } else if (detail.trade_state == "PAYERROR")//支付失败 { return new ResponseMessage { Code = 4 }; //return "4"; ; } } return new ResponseMessage { Code = 0 }; //其他状态 } #endregion #region 返回前端使用的code_url -----自己定义API接口 -----调用NATIVEPayMent 方法传入方法的参数,判断返回结果如果为""说明微信统一下单失败了,可以在统一下单返回结果写入日志文件,查看失败原因。 #endregion ----------ENDAPI--------------------------------------------------------------------------------------------- /// <summary> /// 微信扫码支付 /// </summary> /// <param name="appid">公众号ID</param> /// <param name="boby">商品描述</param> /// <param name="mch_id">商户号</param> /// <param name="spbill_create_ip">终端IP</param> /// <param name="total_fee">金额</param> /// <param name="out_trade_no">商户订单号</param> /// <param name="paysignkey">证书密匙</param> /// <param name="product_id">二维码中包含的商品ID</param> /// <returns></returns> public string NATIVEPayMent (string boby, string spbill_create_ip, Double total_fee, string out_trade_no, string product_id) { UnifiedOrder order = new UnifiedOrder(); order.appid = WXconfig.appid; order.attach = "服务费"; order.body = boby; order.device_info = ""; order.mch_id = WXconfig.mch_id; order.nonce_str = TenpayUtil.getNoncestr(); order.notify_url = Wxconfig.url; order.out_trade_no = out_trade_no; order.product_id = product_id; order.trade_type = "NATIVE"; order.spbill_create_ip = spbill_create_ip; order.total_fee = Convert.ToInt32((total_fee) * 100); TenpayUtil tenpay = new TenpayUtil(); string paySignKey = WXconfig.paysignkey; string code_url = tenpay.getcode_url(order, paySignKey); return code_url; } /// <summary> /// 查询扫码订单情况 /// </summary> /// <param name="out_trade_no">商户订单号</param> /// <returns></returns> public OrderDetail geidingdan(string out_trade_no) { TenpayUtil tenpay = new TenpayUtil(); OrderDetail detail = tenpay.getOrderDetail(out_trade_no); return detail; } public class TenpayUtil { #region url /// <summary> /// 统一支付接口 /// </summary> const string UnifiedPayUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; /// <summary> /// 网页授权接口 /// </summary> const string access_tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token"; /// <summary> /// 微信订单查询接口 /// </summary> const string OrderQueryUrl = "https://api.mch.weixin.qq.com/pay/orderquery"; #endregion #region 随机串,时间截 /// <summary> /// 随机串 /// </summary> public static string getNoncestr() { Random random = new Random(); return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK").ToLower().Replace("s", "S"); } /// <summary> /// 时间截,自1970年以来的秒数 /// </summary> public static string getTimestamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } #endregion /// <summary> /// 网页授权接口 /// </summary> public static string getAccess_tokenUrl() { return access_tokenUrl; } #region 把微信扫码支付的回调XML转换集合 public string GetXml(string xmlstring) { SortedDictionary < string, object> sd= GetInfoFromXml(xmlstring); string reslut = ""; foreach (KeyValuePair<string, object> s in sd) { if (s.Key == "result_code") { reslut= s.Value.ToString(); } } return reslut; } #endregion #region 获取微信签名 /// <summary> /// 获取微信签名 /// </summary> /// <param name="sParams"></param> /// <returns></returns> public string getsign(SortedDictionary<string, object> sParams, string key) { int i = 0; string sign = string.Empty; StringBuilder sb = new StringBuilder(); foreach (KeyValuePair<string, object> temp in sParams) { if (temp.Value.ToString() == "" || temp.Value == null || temp.Key.ToLower() == "sign") { continue; } i++; sb.Append(temp.Key.Trim() + "=" + temp.Value.ToString() + "&"); } sb.Append("key=" + key.Trim() + ""); string signkey = sb.ToString(); sign = MD5Util.GetMD5(signkey, "utf-8"); //utf-8 return sign; } #endregion #region post数据到指定接口并返回数据 /// <summary> /// post数据到指定接口并返回数据 /// </summary> public string PostXmlToUrl(string url, string postData,string type="") { string returnmsg = ""; using (System.Net.WebClient wc = new System.Net.WebClient()) { if (type != "") { Encoding encoding = Encoding.UTF8; wc.Encoding = System.Text.Encoding.GetEncoding("GB2312"); byte[] data = encoding.GetBytes(postData); returnmsg = Encoding.UTF8.GetString(wc.UploadData(url, "POST", data)); } else returnmsg = wc.UploadString(url, "POST", postData); } return returnmsg; } #endregion #region 获取code_url /// <summary> /// 获取code_url /// </summary> public string getcode_url(UnifiedOrder order, string key) { string code_url = ""; string post_data = getUnifiedOrderXml(order, key); string request_data = PostXmlToUrl(UnifiedPayUrl, post_data); //string request_data = HttpRequestutil.RequestUrl(UnifiedPayUrl, post_data, "post"); SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data); foreach (KeyValuePair<string, object> k in requestXML) { if (k.Key == "code_url") { code_url = k.Value.ToString(); break; } } return code_url; } #endregion #region 获取prepay_id /// <summary> /// 获取prepay_id /// </summary> public string getPrepay_id(UnifiedOrder order, string key) { string prepay_id = ""; string post_data = getUnifiedOrderXml(order, key); string request_data = PostXmlToUrl(UnifiedPayUrl, post_data); SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data); foreach (KeyValuePair<string, object> k in requestXML) { if (k.Key == "prepay_id") { prepay_id = k.Value.ToString(); break; } } return prepay_id; } #endregion #region 获取微信订单明细 /// <summary> /// 获取微信订单明细 /// </summary> public OrderDetail getOrderDetail(string out_trade_no) { string post_data = getQueryOrderXml(out_trade_no); string request_data = PostXmlToUrl(OrderQueryUrl, post_data,"1"); OrderDetail orderdetail = new OrderDetail(); SortedDictionary<string, object> requestXML = GetInfoFromXml(request_data); foreach (KeyValuePair<string, object> k in requestXML) { switch (k.Key) { case "retuen_code": orderdetail.result_code = k.Value.ToString(); break; case "return_msg": orderdetail.return_msg = k.Value.ToString(); break; case "appid": orderdetail.appid = k.Value.ToString(); break; case "mch_id": orderdetail.mch_id = k.Value.ToString(); break; case "nonce_str": orderdetail.nonce_str = k.Value.ToString(); break; case "sign": orderdetail.sign = k.Value.ToString(); break; case "result_code": orderdetail.result_code = k.Value.ToString(); break; case "err_code": orderdetail.err_code = k.Value.ToString(); break; case "err_code_des": orderdetail.err_code_des = k.Value.ToString(); break; case "trade_state": orderdetail.trade_state = k.Value.ToString(); break; case "device_info": orderdetail.device_info = k.Value.ToString(); break; case "openid": orderdetail.openid = k.Value.ToString(); break; case "is_subscribe": orderdetail.is_subscribe = k.Value.ToString(); break; case "trade_type": orderdetail.trade_type = k.Value.ToString(); break; case "bank_type": orderdetail.bank_type = k.Value.ToString(); break; case "total_fee": orderdetail.total_fee = k.Value.ToString(); break; case "coupon_fee": orderdetail.coupon_fee = k.Value.ToString(); break; case "fee_type": orderdetail.fee_type = k.Value.ToString(); break; case "transaction_id": orderdetail.transaction_id = k.Value.ToString(); break; case "out_trade_no": orderdetail.out_trade_no = k.Value.ToString(); break; case "attach": orderdetail.attach = k.Value.ToString(); break; case "time_end": orderdetail.time_end = k.Value.ToString(); break; default: break; } } return orderdetail; } #endregion #region #region 把XML数据转换为SortedDictionary /// <summary> /// 把XML数据转换为SortedDictionary<string, string>集合 /// </summary> /// <param name="strxml"></param> /// <returns></returns> protected SortedDictionary<string, object> GetInfoFromXml(string xmlstring) { SortedDictionary<string, object> sParams = new SortedDictionary<string, object>(); try { XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlstring); XmlElement root = doc.DocumentElement; int len = root.ChildNodes.Count; for (int i = 0; i < len; i++) { string name = root.ChildNodes[i].Name; if (!sParams.ContainsKey(name)) { sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim()); } } } catch(Exception ex ) { } return sParams; } #endregion #region 微信统一下单接口xml参数整理 /// <summary> /// 微信统一下单接口xml参数整理 /// </summary> /// <param name="order">微信支付参数实例</param> /// <param name="key">密钥</param> /// <returns></returns> protected string getUnifiedOrderXml(UnifiedOrder order, string key) { string return_string = string.Empty; SortedDictionary<string, object> sParams = new SortedDictionary<string, object>(); sParams.Add("appid", order.appid); sParams.Add("attach", order.attach); sParams.Add("body", order.body); sParams.Add("device_info", order.device_info); sParams.Add("mch_id", order.mch_id); sParams.Add("nonce_str", order.nonce_str); sParams.Add("notify_url", order.notify_url); //当 trade_type=JSAPI 时必输入 sParams.Add("openid", order.openid); //当 trade_type=NATIVE 时必输入 // sParams.Add("product_id", order.product_id); sParams.Add("out_trade_no", order.out_trade_no); sParams.Add("spbill_create_ip", order.spbill_create_ip); sParams.Add("total_fee", order.total_fee); sParams.Add("trade_type", order.trade_type); order.sign = getsign(sParams, key); sParams.Add("sign", order.sign); //拼接成XML请求数据 StringBuilder sbPay = new StringBuilder(); foreach (KeyValuePair<string, object> k in sParams) { if (k.Key == "attach" || k.Key == "body" || k.Key == "sign") { sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">"); } else { sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">"); } } return_string = string.Format("<xml>{0}</xml>", sbPay.ToString()); byte[] byteArray = Encoding.UTF8.GetBytes(return_string); return_string = Encoding.GetEncoding("GBK").GetString(byteArray); Byte[] temp = Encoding.UTF8.GetBytes(return_string); string dataGBK = Encoding.GetEncoding("utf-8").GetString(temp); return return_string; // GBK } #endregion #region 微信订单查询接口XML参数整理 /// <summary> /// 微信订单查询接口XML参数整理 /// </summary> /// <param name="queryorder">微信订单查询参数实例</param> /// <param name="key">密钥</param> /// <returns></returns> protected string getQueryOrderXml(string out_trade_no) { string return_string = string.Empty; SortedDictionary<string, object> sParams = new SortedDictionary<string, object>(); sParams.Add("appid", WXconfig.appid); sParams.Add("mch_id", WXconfig.mch_id); // sParams.Add("transaction_id", queryorder.transaction_id); sParams.Add("out_trade_no", out_trade_no); sParams.Add("nonce_str", getNoncestr()); string sign = getsign(sParams, WXconfig.paysignkey); sParams.Add("sign", sign); //拼接成XML请求数据 StringBuilder sbPay = new StringBuilder(); foreach (KeyValuePair<string, object> k in sParams) { if (k.Key == "attach" || k.Key == "body" || k.Key == "sign") { sbPay.Append("<" + k.Key + "><![CDATA[" + k.Value + "]]></" + k.Key + ">"); } else { sbPay.Append("<" + k.Key + ">" + k.Value + "</" + k.Key + ">"); } } return_string = string.Format("<xml>{0}</xml>", sbPay.ToString().TrimEnd(',')); return return_string; } #endregion #endregion } public class MD5Util { public MD5Util() { // // TODO: 在此处添加构造函数逻辑 // } /// <summary> /// /** 获取大写的MD5签名结果 */ /// </summary> /// <param name="encypStr">数据</param> /// <param name="charset">编码格式</param> /// <returns></returns> public static string GetMD5(string encypStr, string charset) { string retStr; MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider(); //创建md5对象 byte[] inputBye; byte[] outputBye; //使用GB2312编码方式把字符串转化为字节数组. try { inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr); } catch (Exception ex) { inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr); } outputBye = m5.ComputeHash(inputBye); retStr = System.BitConverter.ToString(outputBye); retStr = retStr.Replace("-", "").ToUpper(); return retStr; } /// <summary> /// SHA1加密 /// </summary> /// <param name="str"></param> /// <returns></returns> public static string sha1(string str) { return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "sha1").ToLower(); } }
1.1 获取扫码支付的结果接口(建议轮番获取状态)
请求方式:http get
接口参数说明
名称 | 类型 | 必填 | 说明 |
out_trade_no | String | 是 | 支付订单ID |
返回结果: code :1//支付成功
返回结果: code :2//未支付
返回结果: code :3//用户支付中
返回结果: code :4//支付失败
返回结果: code :0//其他状态
返回结果: code :-1//系统异常
备注:(code 不为-1和1的时候轮番调取接口,建议时间为1s~2s,为-1的时候,提示系统异常,联系管理员。为1的时候跳到完成页面。)
订单查询说明:微信支付虽然有回调(个人认为比较坑),这里我是用了自己支付订单号去查询微信支付的该订单状态。(微信文档有说明,有2个方式,一个回调,一个用支付订单查询订单状态)
以上是关于微信支付----PC扫码支付(查询微信支付订单判断是否支付成功)的主要内容,如果未能解决你的问题,请参考以下文章