首页 > 学院 > 开发设计 > 正文

微信支付 v 3.3.6

2019-11-17 02:46:40
字体:
来源:转载
供稿:网友

微信支付 v 3.3.6

文字说明;

前提:注册、申请服务号,开通微信支付。

涉及到的参数:AppId、AppSecret、原始ID(自动回复)、mch_id(商户号)、Key(商户密钥:自己设定。)

统一规范:

  • 要求
  1. 认证方式:HTTPS 认证,退款和冲正接口调用需要商户证书(证书在审核邮件附件中)。

  2. 请求采用POST 方式。
  3. 提交和返回结果采用xml格式。
  4. 字符集默认使用UTF-8,请勿使用其它字符集。
  5. 商户与微信之间的交互(特别是Native 回调和支付通知回调),都需要验证签名
  6. 处理返回时先判断协议返回错误码,再判断业务返回错误码,最后判断交易状态。
  • 统一加密方式:md5
  • 统一签名生成方式:
    •   传入参数按字段名ascii码从小到大排序,使用url键值对的格式(key1=value1&key2=value2...)拼接成字符串注:值为空的参数不参与签名)。在字符串最后再拼接上&key=Key(商户密钥),然后进行MD5加密处理,最后得到的字符串转换为大写

微信支付:

  • jsapi支付和native支付都需要调用统一支付接口(URL 地址:https://api.mch.weixin.QQ.com/pay/unifiedorder)
  • jsapi支付
    • jsapi 调用统一支付接口需要参数openid(通过Oath2.0授权获取)。
    • 统一支付接口返回参数需要先验证签名,然后获取PRepay_id。
    • document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {  //公众号支付  jQuery('#wxPay').click(function(e){    WeixinJSBridge.invoke('getBrandWCPayRequest',{    "appId" : appId, //公众号名称,由商户传入    "timeStamp" : timeStamp,   //时间戳    "nonceStr" : nonceStr,        //随机串    "package" : package,     //格式:prepay_id=xxxx    "signType" : signType,    //签名方式:MD5    "paySign" : paySign      //签名:生成签名参数appId、timeStamp、nonceStr、package、signType、key 注意参数名大小写。    },function(res){      if(res.err_msg == "get_brand_wcpay_request:ok" ) {        window.location.href=url;   //支付成功后跳转到的页面用于展示      }      // else {        // alert(res.err_code+res.err_desc+res.err_msg);      // }    });   });}, false)
    • 注:jsapi页面点击了两次“微信支付”,生成了两笔订单,需要在页面微信支付按钮上增加防二次点击的机制。
  • native支付
    • 参数product_id必须的
    • 调用统一支付接口获取code_url,并生成二维码图片。

微信支付回调notify_url:

    获取xml格式参数,验证签名,处理逻辑(通知后台会多次回调,先检查是否处理过,在执行)。

代码区:

  • 生成Sign公共方法:
  • public string CreateSign(Dictionary<string, string> collection){  //排序  List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(collection);  list.Sort(delegate(KeyValuePair<string, string> pair1, KeyValuePair<string, string> pair2)  {    return pair1.Key.CompareTo(pair2.Key);  });  StringBuilder sb = new StringBuilder();  foreach (KeyValuePair<string, string> pair in list)  {    sb.Append(pair.Key);    sb.Append("=");    sb.Append(pair.Value);    sb.Append("&");  }  string str = sb.Append("key=value").ToString();  string signValue = MD5(str).ToUpper(); //md5加密并转换成大写  return signValue ;}
  • xml 和 Dictionary 转换方法:
  • public string DictionaryToXml(Dictionary<string, string> collection){  StringBuilder sb = new StringBuilder();  sb.Append("<xml>");  foreach (KeyValuePair<string, string> pair in collection)  {    sb.Append("<" + pair.Key + ">");    sb.Append("<![CDATA[" + pair.Value + "]]>");    sb.Append("</" + pair.Key + ">");  }  sb.Append("</xml>");  return sb.ToString();}public Dictionary<string, string> XmlToDictionary(XmlDocument doc){  Dictionary<string, string> collection = new Dictionary<string, string>();  foreach (XmlElement element in doc.DocumentElement.ChildNodes)  {    string key = element.Name;    string value = element.InnerText;    if (value != "")    {      collection.Add(key, value);    }  }  return collection;}
  • 获取Json某一key值:
  • public string GetJosnValue(string jsonStr, string key){  string result = string.Empty;  if (!string.IsNullOrEmpty(jsonStr))  {    key = "/"" + key.Trim('"') + "/"";    int index = jsonStr.IndexOf(key) + key.Length + 1;    if (index > key.Length + 1)    {      //先截逗号,若是最后一个,截“}”号,取最小值      int end = jsonStr.IndexOf(',', index);      if (end == -1)      {        end = jsonStr.IndexOf('}', index);      }      //index = json.IndexOf('"', index + key.Length + 1) + 1;      result = jsonStr.Substring(index, end - index);      //过滤引号或空格      result = result.Trim(new char[] { '"', ' ', '/'' });    }  }  return result;}

  


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表