微信公众号H5支付步骤

时间:2023-03-09 01:53:51
微信公众号H5支付步骤

微信公众平台:https://mp.weixin.qq.com/

进入 微信支付 管理》开通支付功能。

微信支付|商户平台:

设置安全目录:https://pay.weixin.qq.com/index.php/extend/pay_setting,意思是只有该目录下的页面才能够发起支付请求。

注意保存对应的appid和Appsecret。

接下来是微信的授权js,Authorize.cshtml

<script type="text/javascript">
var code = GetQueryString("code");
var state = GetQueryString("state");
if (code == null || code == undefined || code == "") {
//步骤1:第一次进入本页面,先获取微信的授权code,然后再跳转会本页面,这时候微信会自动加上code参数
var REDIRECT_URI = encodeURI("http://www.xxx.com/Home/Authorize");
var url2 = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxx&redirect_uri=" + REDIRECT_URI + "&response_type=code&scope=snsapi_userinfo&state=" + state + "#wechat_redirect";
window.location.href = url2;
}
else {
//步骤1会重新返回到本页面,并携带code参数,然后进入步骤2:服务器端获取openid
$.ajax({
type: "GET",
url: "/WX/GetToken",
data: { code: code },
success: function (result) {
var data = $.parseJSON(result);
if (data.openid != null && data.openid != "" && data.openid != undefined) {
if (data.IsFirst) {
window.location.href = "/UInfo/UData?state=" + state;
}
else {
if (state == ) {
window.location.href = "/BInfo/Index";
}
else if (state == ) {
window.location.href = "/CInfo/Index";
}
else {
window.location.href = "/UInfo/Index";
}
}
}
else {
alert(data.errmsg);
}
}
});
}
</script>

服务器端代码:

     /// <summary>
/// 微信授权登录,获取微信用户基础数据、生成AccessToken、注册用户,WX/GetToken?code=xxx
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[HttpGet]
public ContentResult GetToken(string code)
{
JavaScriptSerializer js = new JavaScriptSerializer();
try
{
//获取token
WXAuthorizeModel authorizeModel = GetWXAuthorizeInfo(code); if (authorizeModel != null && authorizeModel.errcode == )
{
//记录token,获取数据库中已存在的该用户的 WX token
Models.WXMPTokensInfo tokensInfo = WXMPTokensInfoBLL.GetDataByOpenId(authorizeModel.openid);
if (tokensInfo == null)
{
tokensInfo = new Models.WXMPTokensInfo();
} tokensInfo.access_token = authorizeModel.access_token;
tokensInfo.CreateDate = DateTime.Now;
tokensInfo.EndDate = DateTime.Now.AddSeconds(authorizeModel.expires_in);
tokensInfo.expires_in = authorizeModel.expires_in;
tokensInfo.openid = authorizeModel.openid;
tokensInfo.refresh_token = authorizeModel.refresh_token;
tokensInfo.scope = authorizeModel.scope;
int no = ;
if (tokensInfo.ID > )
{
no = WXMPTokensInfoBLL.Modify(tokensInfo);
}
else
{
no = WXMPTokensInfoBLL.Add(tokensInfo);
}
//获取微信用户个人资料
WXUserInfo wxuserInfo = GetWXUserInfo(authorizeModel.openid);
Models.UserInfo userInfo = UserInfoBLL.GetEntityByOpenID(authorizeModel.openid);
if (userInfo == null)
{
userInfo = new Models.UserInfo();
}
userInfo.city = wxuserInfo.city;
userInfo.country = wxuserInfo.country;
userInfo.headimgurl = wxuserInfo.headimgurl;
userInfo.nickname = wxuserInfo.nickname;
userInfo.openid = wxuserInfo.openid;
userInfo.privilege = "";//wxuserInfo.privilege;
userInfo.province = wxuserInfo.province;
userInfo.sex = wxuserInfo.sex;
userInfo.unionid = wxuserInfo.unionid;
//保存、更新微信用户资料
bool isFirst = true;
int no2 = ;
if (userInfo.ID > )
{
isFirst = false;
no2 = UserInfoBLL.ModifyEntity(userInfo);
}
else
{
no2 = UserInfoBLL.Append(userInfo);
userInfo.ID = no2;
}
//设置session
Session["UModel"] = userInfo;
//设置cookie保存微信openid
CookiesHelper.setCookie("openid", authorizeModel.openid, ); //返回json数据给页面
var data = new
{
authorizeModel.openid,
authorizeModel.errcode,
authorizeModel.errmsg,
IsFirst = isFirst
};
return Content(js.Serialize(data));
}
//token获取失败,返回-1
return Content(js.Serialize(new { openid = "", errcode = -, authorizeModel.errmsg }));
}
catch (Exception ex)
{
Log.Error("GetWXToken", ex.Message);
return Content(js.Serialize(new { openid = "", errcode = -, ex.Message }));
}
}

获取微信token:

/// <summary>
/// 获取微信授权信息(AccessToken)
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
public WXAuthorizeModel GetWXAuthorizeInfo(string code)
{
string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=xxxxxx&secret=xxxxxx&code=" + code + "&grant_type=authorization_code";
string result = Utils.ClientRequest(url, "", "GET");//这是一个发送Http请求的函数,博客园里很多,自己搜就好了,我以前的文章里也有。 JavaScriptSerializer js = new JavaScriptSerializer();
WXAuthorizeModel authorizeModel = js.Deserialize<WXAuthorizeModel>(result);
return authorizeModel;
}
/// <summary>
/// 获取微信用户数据
/// </summary>
/// <param name="openid"></param>
/// <returns></returns>
public WXUserInfo GetWXUserInfo(string openid)
{
Models.WXMPTokensInfo tokensInfo = WXMPTokensInfoBLL.GetDataByOpenId(openid);
if (tokensInfo != null && tokensInfo.EndDate > DateTime.Now)//如果Token的有效期已经过了,则要重新获取Token
{
string url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + tokensInfo.access_token + "&openid=" + openid + "&lang=zh_CN";
string result = Utils.ClientRequest(url, "", "GET");
JavaScriptSerializer js = new JavaScriptSerializer();
WXUserInfo wXUser = js.Deserialize<WXUserInfo>(result);
return wXUser;
}
return null;
} public class WXAuthorizeModel
{
public string access_token { get; set; }
public int expires_in { get; set; }
public string refresh_token { get; set; }
public string openid { get; set; }
public string scope { get; set; }
public int errcode { get; set; }
public string errmsg { get; set; }
}

微信支付参数和通知:

/// <summary>
/// 生成微信支付js参数
/// /WX/GeneralWXPayPara
/// {"openid":"xxxx"}
/// openid:微信用户openid;
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[AcceptVerbs("POST")]
public ContentResult GeneralWXPayPara(WXPayModel data)
{
JavaScriptSerializer js = new JavaScriptSerializer();
try
{
string openid = data.openid;if (!string.IsNullOrEmpty(openid))
{
Models.UserInfo userinfo = UserInfoBLL.GetEntityByOpenID(openid);
if (userinfo != null)
{
int total_fee = 1;//单位:分
string body = "test";
string attach = "";//这是用户自定义附加的字符串,在通知接口中会携带返回,很重要,可以传自己业务逻辑的标识。string tradeNo = WxPayApi.GenerateOutTradeNo();//下载的微信SDK中自带的函数
//若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数
JsApiPay jsApiPay = new JsApiPay();
jsApiPay.openid = openid;
jsApiPay.total_fee = total_fee; //JSAPI支付预处理
WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult(body, attach, tradeNo);//这个函数是我修改的,下载的微信SDK里一些参数他是写死的,我改成传参了。
string wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数
return Content(js.Serialize(new { code = , msg = "操作成功", data = wxJsApiParam }));
}
else
{
return Content(js.Serialize(new { code = -, msg = "用户不存在" }));//用户不存在
}
}
else
{
return Content(js.Serialize(new { code = -, msg = "参数异常" }));//参数异常
}
}
catch (Exception ex)
{
Log.Error("WX/GeneralWXPayPara", ex.Message);
return Content(js.Serialize(new { code = -, msg = "系统异常:" + ex.Message }));//系统异常
}
} /// <summary>
/// 微信支付异步通知
/// http://www.xxx.com/WX/WXNotify
/// </summary>
/// <returns></returns>
[AcceptVerbs("POST", "GET")]
public ContentResult WXNotify()
{
try
{
WxPayData res = new WxPayData();
ResultNotify resultNotify = new ResultNotify();
string xmlStr = resultNotify.ProcessNotify();//获取通知结果
WxPayData notifyData = resultNotify.notifyData;
//判断通知合法
if (resultNotify.Success)
{
string return_code = ""; //SUCCESS/FAIL,这个要进行判断的,因为微信可能会传null过来。
if (notifyData.GetValue("return_code") != null)
{
return_code = notifyData.GetValue("return_code").ToString();
}
string return_msg = "";
if (notifyData.GetValue("return_msg") != null)
{
return_msg = notifyData.GetValue("return_msg").ToString();
}
//判断是否通信成功
if (return_code == "SUCCESS")
{
string result_code = "";
if (notifyData.GetValue("result_code") != null)
{
result_code = notifyData.GetValue("result_code").ToString();
} string err_code_des = "";
if (notifyData.GetValue("err_code_des") != null)
{
err_code_des = notifyData.GetValue("err_code_des").ToString();
}
//判断支付成功
if (result_code == "SUCCESS")
{
string openid = notifyData.GetValue("openid").ToString();
string out_trade_no = notifyData.GetValue("out_trade_no").ToString();
int total_fee = Convert.ToInt32(notifyData.GetValue("total_fee").ToString());
int attach = Convert.ToInt32(notifyData.GetValue("attach").ToString());//附加字符串(商品ID)
Models.UserInfo userinfo = UserInfoBLL.GetEntityByOpenID(openid);
int no1 = ;
//生成订单信息
Models.TradeInfo model = new Models.TradeInfo();
model.CreateDate = DateTime.Now;
model.Description = "";
if (userinfo != null)
{
model.Description = "userid:" + userinfo.ID + ";openid:" + openid + ";NickName:" + userinfo.nickname + ";Mobile:" + userinfo.Mobile + ";";
}
model.PayMethod = Convert.ToInt32(Common.EnumHelper.TradePayMethod.微信); model.TradeTypeID = 1;
model.ProID = attach;
model.Title = "购买商品"; model.TotalFee = Convert.ToDouble(total_fee) / ;//把金额的单位 分 转化为 圆
model.TradeNo = out_trade_no;
model.TradeStatus = "SUCCESS";
model.UserID = userinfo.ID;
no1 = TradeInfoBLL.Append(model);
Log.Error("WX/WXNotify", "添加订单"); if (no1 > )
{ res.SetValue("return_code", "SUCCESS");
res.SetValue("return_msg", "OK");
return Content(res.ToXml()); }
}
else
{
Log.Error("WX", "支付失败 : " + err_code_des);
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "支付失败:" + err_code_des);
return Content(res.ToXml());
}
}
else
{
Log.Error("WX", "通信失败 : " + return_msg);
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "通信失败:" + return_msg);
return Content(res.ToXml());
}
} res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "逻辑处理异常");
return Content(res.ToXml());
}
catch (Exception ex)
{
WxPayData res = new WxPayData();
res.SetValue("return_code", "FAIL");
res.SetValue("return_msg", "系统处理异常");
Log.Error("WX", "WXNotify Exception : " + ex.ToString());
return Content(res.ToXml());
}
}

发起微信支付的js:

function BuyProduct(openid, proid) {
callpay(openid, , proid);
}
function BuyVip(openid) {
callpay(openid, , );
}
//调用微信JS api 支付
function jsApiCall(openid, TradeTypeID, ProID) {
//生成支付参数
$.ajax({
type: "POST",
dataType: "json",
url: "/WX/GeneralWXPayPara",
data: { openid: openid, TradeTypeID: TradeTypeID, ProID: ProID },
success: function (result) {
if (result.code == ) {
//进入支付
var jd = $.parseJSON(result.data);//注意转化成json数据
WeixinJSBridge.invoke('getBrandWCPayRequest', jd, function (res) {
//alert(JSON.stringify(res));//提示支付结果
if (res.err_msg == "get_brand_wcpay_request:ok") {
alert("支付成功");
}
else {
alert("支付失败");
}
});
}
else {
alert(result.msg);
}
}
});
} function callpay(openid, TradeTypeID, ProID) {
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}
else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}
else {
jsApiCall(openid, TradeTypeID, ProID);
}
}