微信公众号支付
分类:
IT文章
•
2025-01-26 15:19:07
1.获取用户open_id
/// <summary>
/// 获取openid 并返回视图
/// </summary>
/// <param name="Code"></param>
/// <param name="OrderGuid"></param>
/// <returns></returns>
public ActionResult VisaPay(string Code, Guid OrderGuid)
{
try
{
var appid = "wxxxxxxxxxxxxxxxxxxxxxxx";
var secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
if (string.IsNullOrEmpty(Code))
{
//向微信发送请求 获取code
string url1 = UrlEncode("http://wechat.yimalx.com/WeChatSite/WeChatPay/VisaPay?orderGuid=" + OrderGuid);
var url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect", appid, url1);
return Redirect(url);
}
else
{
//获取token
var client = new System.Net.WebClient();
client.Encoding = System.Text.Encoding.UTF8;
var url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appid, secret, Code);
var data = client.DownloadString(url);
var serializer = new JavaScriptSerializer();
var obj = serializer.Deserialize<Dictionary<string, string>>(data);
string accessToken;
if (!obj.TryGetValue("access_token", out accessToken))
return Redirect("404");
var opentid = obj["openid"];
var model = OrderInfoManager.Instance.GetById(OrderGuid);
ViewData["PayAmount"] = model.PayAmount;
ViewData["OrderGuid"] = OrderGuid;
string str = WeChatPayHelper.GoToWeCharJSPay(OrderGuid, opentid);
CreateLog.SaveLogs("str==============================" + str + "=================================", 1);
var codeId = new XmlDocument();
codeId.LoadXml(str);
var info = new WeChatInfo();
//8.读取xml节点的值
info.return_code = codeId.SelectSingleNode("xml/return_code").InnerText;
info.return_msg = codeId.SelectSingleNode("xml/return_msg").InnerText;
info.appid = codeId.SelectSingleNode("xml/appid").InnerText;
info.mch_id = codeId.SelectSingleNode("xml/mch_id").InnerText;
info.nonce_str = codeId.SelectSingleNode("xml/nonce_str").InnerText;
info.openid = opentid;
info.sign = codeId.SelectSingleNode("xml/sign").InnerText;
info.result_code = codeId.SelectSingleNode("xml/result_code").InnerText;
info.prepay_id = codeId.SelectSingleNode("xml/prepay_id").InnerText;
info.trade_type = codeId.SelectSingleNode("xml/trade_type").InnerText;
string timestamp = WeChatPayHelper.GetTimeStamp();
var res = new Dictionary<string, object>
{
{"appId", info.appid },
{"nonceStr", info.nonce_str},
{"timeStamp",timestamp},
{"signType","MD5"},
{"package","prepay_id="+info.prepay_id}
};
info.sign = WeChatPayHelper.GetSignString(res);
info.timeStamp = timestamp;
return View(info);
}
}
catch (Exception e)
{
CreateLog.SaveLogs(e.Message, 0);
return Redirect("WeChatSite/WeChatPay/VisaPay?OrderGuid=" + OrderGuid);
}
}
GetOpen_id
2.调用统一下单接口生成预付款单
/// <summary>
/// 微信客户端内部提交支付申请
/// </summary>
/// <param name="orderGuid"></param>
/// <returns></returns>
[HttpGet]
public static string GoToWeCharJSPay(Guid orderGuid, string token)
{
var weCharUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
var model = OrderInfoManager.Instance.GetById(orderGuid);
unifiedorder unOrder = new unifiedorder();
unOrder.appid = ConfigurationManager.AppSettings["wx_appid"];
unOrder.mch_id = ConfigurationManager.AppSettings["wx_mch_id"];
unOrder.nonce_str = Guid.NewGuid().ToString().Replace("-", "");
unOrder.sign = "";
unOrder.body = model.ProductName;
unOrder.out_trade_no = model.OrderCode;
//payAmountmodel.PayAmount
unOrder.total_fee = Convert.ToInt32(model.PayAmount * 100);
unOrder.spbill_create_ip = GetWebClientIp();
unOrder.notify_url = ConfigurationManager.AppSettings["wechatUrl"] + "WeChatSite/WeChatPay/ProcessingCallback";
unOrder.trade_type = "JSAPI";
unOrder.openid = token;
unOrder.device_info = "WEB";
var dc = new Dictionary<string, object>()
{
{"appid",unOrder.appid},
{"mch_id",unOrder.mch_id},
{"total_fee",unOrder.total_fee},
{"out_trade_no",unOrder.out_trade_no},
{"body",unOrder.body},
{"notify_url",unOrder.notify_url},
{"trade_type",unOrder.trade_type},
{"nonce_str",unOrder.nonce_str},
{"spbill_create_ip",unOrder.spbill_create_ip},
{"openid",unOrder.openid},
//{"scene_info","h5_info"}
};
dc.Add("sign", GetSignString(dc));//签名
//2.将参数转换为xml格式
var sb = new StringBuilder();
sb.Append("<xml>");
foreach (var d in dc)
{
sb.Append("<" + d.Key + ">" + d.Value + "</" + d.Key + ">");
}
sb.Append("</xml>");
//应用场景信息
//1.创建请求连接
var request = (HttpWebRequest)WebRequest.Create(weCharUrl);
//2.设置参数
var data = Encoding.UTF8.GetBytes(sb.ToString());
//4.设置属性
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
//5.将转换后的参数以文件流的形式写入到请求中
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
//6.声明变量,获取响应
var response = (HttpWebResponse)request.GetResponse();
//7.以文件流的方式读取响应结果
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
//
return responseString;
}
GoToWeCharJSPay
3.回调
1).同步回调:前端拉起微信支付界面,判断支付结果
<script>
function onBridgeReady() {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": "@Model.appid", //公众号名称,由商户传入
"timeStamp": "@Model.timeStamp", //时间戳,自1970年以来的秒数
"nonceStr": "@Model.nonce_str", //随机串
"package": "prepay_id=@Model.prepay_id",
"signType": "MD5", //微信签名方式:
"paySign": "@Model.sign" //微信签名
},
function (res) {
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
if (res.err_msg == "get_brand_wcpay_request:ok") {
alert("支付成功");
window.location.href = "/WeChatSite/Home/Index";
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
alert("支付过程中用户取消");
} else if (res.err_msg == "get_brand_wcpay_request:fail") {
alert("支付失败");
}
}
);
}
$(".immediate_payment").click(function () {
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
});
</script>
View Code
/// <summary>
/// 处理回调数据
/// </summary>
public ActionResult ProcessingCallback()
{
//1.获取微信支付回调信息
string XmlData = getPostStr();
//判断数据是否为空
if (XmlData.IsNotNullOrEmpty())
{
DataSet ds = new DataSet();
StringReader sr = new StringReader(XmlData);
XmlTextReader dataReader = new XmlTextReader(sr);
ds.ReadXml(dataReader);
CreateLog.SaveLogs("--------------------XMLData&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" + XmlData + "&&&&&&&&&&&&&&&&&&&", 1);
if (ds.Tables[0].Rows[0]["return_code"].ToString() == "SUCCESS")
{
#region 解析ds获取对象
//将dataset转换为对象
WeChatPaymentReturn wcpr = new WeChatPaymentReturn()
{
appid = ds.Tables[0].Rows[0]["appid"].ToString(),
bank_type = ds.Tables[0].Rows[0]["bank_type"].ToString(),
cash_fee = ds.Tables[0].Rows[0]["cash_fee"].ToString(),
fee_type = ds.Tables[0].Rows[0]["fee_type"].ToString(),
is_subscribe = ds.Tables[0].Rows[0]["is_subscribe"].ToString(),
mch_id = ds.Tables[0].Rows[0]["mch_id"].ToString(),
nonce_str = ds.Tables[0].Rows[0]["nonce_str"].ToString(),
openid = ds.Tables[0].Rows[0]["openid"].ToString(),
out_trade_no = ds.Tables[0].Rows[0]["out_trade_no"].ToString(),
result_code = ds.Tables[0].Rows[0]["result_code"].ToString(),
return_code = ds.Tables[0].Rows[0]["return_code"].ToString(),
time_end = ds.Tables[0].Rows[0]["time_end"].ToString(),
total_fee = ds.Tables[0].Rows[0]["total_fee"].ToString(),
trade_type = ds.Tables[0].Rows[0]["trade_type"].ToString(),
transaction_id = ds.Tables[0].Rows[0]["transaction_id"].ToString(),
sign = ds.Tables[0].Rows[0]["sign"].ToString(),
};
#endregion
//4.支付成功之后验证Sign
var againSign = new Dictionary<string, object>();
againSign.Add("appid", wcpr.appid);
againSign.Add("bank_type", wcpr.bank_type);
againSign.Add("cash_fee", wcpr.cash_fee);
againSign.Add("fee_type", wcpr.fee_type);
againSign.Add("is_subscribe", wcpr.is_subscribe);
againSign.Add("mch_id", wcpr.mch_id);
againSign.Add("nonce_str", wcpr.nonce_str);
againSign.Add("openid", wcpr.openid);
againSign.Add("out_trade_no", wcpr.out_trade_no);
againSign.Add("result_code", wcpr.result_code);
againSign.Add("return_code", wcpr.return_code);
againSign.Add("time_end", wcpr.time_end);
againSign.Add("total_fee", wcpr.total_fee);
againSign.Add("trade_type", wcpr.trade_type);
againSign.Add("transaction_id", wcpr.transaction_id);
string againSignStr = WeChatPayHelper.GetSignString(againSign);
if (wcpr.sign.ToUpper() == againSignStr.ToUpper())
{
CreateLog.SaveLogs("####签名验证成功againSignStr######" + againSignStr + "-------sign-------------" + wcpr.sign, 1);
#region 处理数据逻辑
//更新订单信息
//添加支付信息
CreateLog.SaveLogs("开始付款", 1);
//签名正确 处理订单操作逻辑
var oderInfo = OrderInfoManager.Instance.GetByField("OrderCode", wcpr.out_trade_no).FirstOrDefault();
if (oderInfo.OrderState != (int)OrderState.代付款)
{
CreateLog.SaveLogs("支付成功!但是在此发出请求", 1);
return null;
}
if (oderInfo != null)
{
try
{
OrderInfoManager.Instance.UpdataStatus(oderInfo.Guid, (int) OrderState.已付款);
CreateLog.SaveLogs("状态修改结束", 1);
PaymentInfo info = new PaymentInfo()
{
OrderGuid = oderInfo.Guid,
PayState = 1,
PayMethod = (int)PayMethod.微信支付,
Guid = Guid.NewGuid(),
Mark = (int)DataMark.正常,
PayDateTime = DateTime.Now,
PayMoney = Convert.ToDecimal(wcpr.total_fee) / 100,
Qid = wcpr.transaction_id
};
PaymentInfoManager.Instance.Insert(info);
CreateLog.SaveLogs("支付信息添加成功", 1);
}
catch (Exception e)
{
CreateLog.SaveLogs("-----Exception" + e,1);
throw;
}
}
//CreateLog.SaveLogs("状态修改结束", 1);
#endregion
}
else
{
CreateLog.SaveLogs("####签名验证失败againSignStr######" + againSignStr + "-------sign-------------" + wcpr.sign, 1);
}
}
else
{
// 返回信息,如非空,为错误原因 签名失败 参数格式校验错误
string return_msg = ds.Tables[0].Rows[0]["return_msg"].ToString();
CreateLog.SaveLogs("支付失败", 1);
}
}
return View();
}
//getPostStr
/// <summary>
/// 获取微信支付毁掉的数据;
/// </summary>
/// <returns></returns>
public string getPostStr()
{
Int32 intLen = Convert.ToInt32(Request.InputStream.Length);
byte[] b = new byte[intLen];
Request.InputStream.Read(b, 0, intLen);
return System.Text.Encoding.UTF8.GetString(b);
}