openid:用户openId
outTradeNo:订单编号
description:商品描述
totalFee:金额
public string UnifiedOrder(string openid, string outTradeNo, string description, int totalFee)
{
// 构造请求参数
SortedDictionary<string, object> parameters = new SortedDictionary<string, object>();
parameters.Add("appid", appId);
parameters.Add("mch_id", mchId);
parameters.Add("nonce_str", GetNonceStr());
parameters.Add("body", description);
parameters.Add("out_trade_no", outTradeNo);
parameters.Add("total_fee", totalFee.ToString());
parameters.Add("spbill_create_ip", "127.0.0.1");
parameters.Add("notify_url", notifyUrl);
parameters.Add("trade_type", "JSAPI");
parameters.Add("openid", openid);
// 签名
string sign = CreateSign(parameters, AES_KEYV2);
parameters.Add("sign", sign);
// 转换为XML格式
string xml = DictionaryToXml(parameters);
// 发送POST请求到微信支付服务器
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://api.mch.weixin.qq.com/pay/unifiedorder");
request.Method = "POST";
request.ContentType = "text/xml";
byte[] data = Encoding.UTF8.GetBytes(xml);
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data, 0, data.Length);
stream.Close();
// 获取响应
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string result = reader.ReadToEnd();
reader.Close();
response.Close();
// 解析XML格式的响应
XmlDocument doc = new XmlDocument();
doc.LoadXml(result);
XmlNode rootNode = doc.SelectSingleNode("xml");
string returnCode = rootNode.SelectSingleNode("return_code").InnerText;
string resultCode = rootNode.SelectSingleNode("result_code").InnerText;
if (returnCode == "SUCCESS" && resultCode == "SUCCESS")
{
// 生成JSAPI支付参数
SortedDictionary<string, object> jsApiParameters = new SortedDictionary<string, object>();
jsApiParameters.Add("appId", appId);
jsApiParameters.Add("timeStamp", GetTimestamp());
jsApiParameters.Add("nonceStr", GetNonceStr());
jsApiParameters.Add("package", "prepay_id=" + rootNode.SelectSingleNode("prepay_id").InnerText);
jsApiParameters.Add("signType", "MD5");
// 签名
string jsApiSign = CreateSign(jsApiParameters, AES_KEYV2);
jsApiParameters.Add("paySign", jsApiSign);
// 转换为JSON格式并返回
return DictionaryToJson(jsApiParameters);
}
else
{
throw new Exception(rootNode.SelectSingleNode("err_code_des").InnerText);
}
}
// 创建签名
private string CreateSign(SortedDictionary<string, object> parameters, string key)
{
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, object> pair in parameters)
{
if (!string.IsNullOrEmpty(pair.Value.ToString()))
{
sb.Append(pair.Key + "=" + pair.Value + "&");
}
}
sb.Append("key=" + key);
return GetMd5(sb.ToString()).ToUpper();
}
// 获取MD5哈希值
private string GetMd5(string str)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] data = Encoding.UTF8.GetBytes(str);
byte[] hash = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
// 获取随机字符串
private string GetNonceStr()
{
Random random = new Random();
return GetMd5(random.Next(1000).ToString());
}
// 获取时间戳
private string GetTimestamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
// 将字典转换为XML格式
private string DictionaryToXml(SortedDictionary<string, object> dictionary)
{
StringBuilder sb = new StringBuilder();
sb.Append("<xml>");
foreach (KeyValuePair<string, object> pair in dictionary)
{
if (!string.IsNullOrEmpty(pair.Value.ToString()))
{
sb.Append("<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">");
}
}
sb.Append("</xml>");
return sb.ToString();
}
// 将字典转换为JSON格式
private string DictionaryToJson(SortedDictionary<string, object> dictionary)
{
StringBuilder sb = new StringBuilder();
sb.Append("{");
foreach (KeyValuePair<string, object> pair in dictionary)
{
if (!string.IsNullOrEmpty(pair.Value.ToString()))
{
sb.Append("\"" + pair.Key + "\":\"" + pair.Value + "\",");
}
}
sb.Remove(sb.Length - 1, 1);
sb.Append("}");
return sb.ToString();
}
其中 appId 微信appId,mchId商户号,notifyUrl回调地址,AES_KEYV2:v2秘钥
//前端js
var local = encodeURIComponent(window.location.href);
var appid = $("#appId").text();
var url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + appid + '&redirect_uri=' + local + '&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect';
window.location.href = url;
var url ="Wechat/Pay?code=" + code;
$.ajax({
type: "GET",
url: url,
contentType: "application/x-www-form-urlencoded",
success: function (res) {
if (res.code == "1") {
var response = res.data;
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": response.appId, //公众号ID,由商户传入
"timeStamp": response.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr": response.nonceStr, //随机串
"package": response.package,
"signType": response.signType, //微信签名方式:
"paySign": response.paySign//微信签名
}, function (res) {
if (res.err_msg == "get_brand_wcpay_request:cancel") {
hintIfno("支付已经取消");
return false;
} else if (res.err_msg == "get_brand_wcpay_request:ok") {
hintIfno("支付成功");
} else {
hintIfno("支付失败,请返回列表页重新支付");
}
});
} else {
}
}
});