本文问主要介绍接入微信支付中服务端的代码集成过程,运用的开发工具为VS(Visual Studio)。我用的是微信支付之前的接口,不是V3的。Http请求方式为post,参数格式为xml(官网说明文档)
一、调用微信支付统一下单接口。在APP选择微信支付的接口中调用如下方法
//微信支付
public static string wxpay(string totalAmount, string simChargeMsg) {
totalAmount = (float.Parse(totalAmount) * 100).ToString();//微信支付的金额单位为分,所以先将金额元转换为分
//统一下单
string WebUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";//换成接收方的URL
//统一下单参数
Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("appid", WXPay_APPID);//APPID
dic.Add("attach", simChargeMsg); //支付信息
dic.Add("body", "商品描述");
dic.Add("mch_id", WXPay_MchID);//商户号
dic.Add("nonce_str", CreatenNonce_str());//随机数生成
dic.Add("notify_url", "https://pay.weixin.qq.com/wxpay/pay.action");//通知地址
dic.Add("out_trade_no", DateTime.Now.ToString("yyyyMMddHHmmss"));//商户订单号 要求统一商户号下唯一,所以我设置为当前时间
dic.Add("total_fee", totalAmount);//总金额 单位为分
dic.Add("trade_type", "APP"); //交易类型 APP
//根据当前添加的参数生成签名
string signValue = GetSignature(dic);
//添加参数 签名
dic.Add("sign", signValue);
//网络请求
string res = wxRequestUrl(WebUrl, wxGetXml(dic));//wxGetXml() 生成xml型参数
var doc = new System.Xml.XmlDocument(); //实例化XmlDocument
doc.LoadXml(res);//解析请求结果数据
XmlNode xml_node = doc.SelectSingleNode("xml");
if (xml_node != null && xml_node.SelectSingleNode("result_code")!= null && xml_node.SelectSingleNode("result_code").InnerText == "SUCCESS")
{
//请求成功时 将返回参数整理生成Json字符串传递给APP
Dictionary<string, string> dic01 = new Dictionary<string, string>();
dic01.Add("appid", xml_node.SelectSingleNode("appid").InnerText);//APPID
dic01.Add("timestamp", CreatenTimestamp().ToString());//时间戳
dic01.Add("noncestr", CreatenNonce_str());//随机字符串
dic01.Add("prepayid", xml_node.SelectSingleNode("prepay_id").InnerText);//预支付交易会话id
dic01.Add("partnerid", xml_node.SelectSingleNode("mch_id").InnerText);//商户号
dic01.Add("package", "Sign=WXPay");
dic01.Add("sign", GetSignature(dic01));//根据参数生成签名 并加入到参数中
string json = JsonConvert.SerializeObject(dic01); //生成Json字符串
return json;
}
return "微信支付失败";
}
其中的的随机数生成、时间戳、生成XML参数、发送网络请求、签名方法会在下面展示。参数说明
二、随机数生成
private static string[] strs = new string[]
{
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
};
//16位随机数生成
public static string CreatenNonce_str()
{
Random r = new Random();
var sb = new StringBuilder();
var length = strs.Length;
for (int i = 0; i < 16; i++)
{
sb.Append(strs[r.Next(length - 1)]);
}
return sb.ToString();
}
三、时间戳
//时间戳
public static long CreatenTimestamp()
{
return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
}
四、生成XML参数
public static string wxGetXml(Dictionary<string, string> dic)//要发送的XML
{
StringBuilder strBuilder = new StringBuilder();
strBuilder.Append("<xml>");
foreach (string key in dic.Keys)
{
strBuilder.Append("<" + key + ">" + dic[key] + "</" + key + ">");
}
strBuilder.Append("</xml>");
return strBuilder.ToString();
}
五、发送网络请求
public static string wxRequestUrl(string url, string data)
{
var request = WebRequest.Create(url);
request.Method = "post";
request.ContentType = "text/xml";
request.Headers.Add("charset:utf-8");
var encoding = Encoding.GetEncoding("utf-8");
if (data != null)
{
byte[] buffer = encoding.GetBytes(data);
request.ContentLength = buffer.Length;
request.GetRequestStream().Write(buffer, 0, buffer.Length);
}
else
{
request.ContentLength = 0;
}
using (HttpWebResponse wr = request.GetResponse() as HttpWebResponse)
{
using (StreamReader reader = new StreamReader(wr.GetResponseStream(), encoding))
{
return reader.ReadToEnd();
}
}
}
六、签名
//签名算法
public static string GetSignature(Dictionary<string, string> dic)
{
//第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序
List<String> list = new List<String>();
foreach (string key in dic.Keys)
{
list.Add(key + "=" + dic[key]);
}
list.Sort();
String stringA = String.Join("&", list);
//第二步:拼接API密钥,WXPay_V2Key是在微信商户平台上设置的API秘钥
String stringSignTemp = stringA + "&key="+WXPay_V2Key;
//第三步:MD5加密生成签名
String sign = md5Password(stringSignTemp.ToString());
return sign;
}
//MD5加密算法
public static String md5Password(String key)
{
var md5 = MD5.Create();
var bytValue = Encoding.UTF8.GetBytes(key);
var bytHash = md5.ComputeHash(bytValue);
var sb = new StringBuilder();
foreach (var b in bytHash)
{
sb.Append(b.ToString("X2"));
}
return sb.ToString().ToUpper();//换成大写
}