DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,minimum-scale=1,user-scalable=no,maximum-
scale=1,initial-scale=1" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no" />
<script src="../js/jquery-1.7.2.min.js" type="text/javascript">script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js">script>
<script type="text/javascript">
wx.config({
debug: false,// 为true时,启用调试功能,微信会把错误信息以alert的形式弹出
appId: '<%=WxConfig.AppID%>', // 必填,公众号的唯一标识
timestamp: <%=WxConfig.Timestamp%>,//时间戳
nonceStr: "<%=WxConfig.NonceStr%>",//随机字符串
signature: "<%=WxConfig.Signature%>", //权限签名 与微信支付签名没有半毛钱关系
jsApiList: [// 必填,需要使用的JS接口列表
'onMenuShareTimeline',
'onMenuShareAppMessage',
'getNetworkType',
'chooseWXPay'
]
});
function callPay() {
wx.chooseWXPay({
timestamp: <%=WxConfig.Timestamp%>, // 支付签名时间戳
nonceStr: "<%=WxConfig.NonceStr%>", // 支付签名随机串
package: "<%=WxConfig.Package%>", // 统一支付接口返回的package包
signType: "<%=WxConfig.SignType%>", // 签名方式,'MD5'
paySign: "<%=WxConfig.PaySign %>", // 支付签名
success: function (res) {
// 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok
,但并不保证它绝对可靠。
if (res.err_msg == "get_brand_wcpay_request:ok") {
location.href = "<%=WxConfig.ReturnUrl%>?sp_billno=<%=sp_billno%>";
} else {
alert("支付未完成");
}
}
});
}
<%if (Flag == "1")
{%>
$(function () {
callPay();
});
<%}%>
script>
head>
<body>
<form id="form2" runat="server">
<div id="block_top">
<span class="block_top_l"><a href="Index.aspx">a>span>
<h1>捐赠信息h1>
div>
<div class="login_btn">
<input type="button" id="rePay" onclick="callPay()" value="重新支付" />
div>
form>
body>
html>
public partial class pay3 : PageBase { public string Flag = "0"; public string sp_billno = string.Empty; public WxConfig WxConfig = new WxConfig(); public tb_Deposit Deposit = new tb_Deposit(); public int depId = 0; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { try { InitWxConfig();// 初始化微信公众号配置信息。 InitTacket();// 初始化捐赠票据。 InitPackage();// 初始化支付包参数。 } catch (Exception ex) { Log.Write(typeof(pay3), ex.Message, ex); } } } public void InitWxConfig() { WxConfig.Timestamp = TenpayUtil.getTimestamp(); WxConfig.NonceStr = TenpayUtil.getNoncestr(); WxConfig.SignType = "MD5"; WxConfig.PaySign = string.Empty; if (Session["openid"] == null || string.IsNullOrEmpty(Session["openid"].ToString())) { GetOpenId(); } WxConfig.OpenId = (string)Session["openid"]; } public void InitTacket() { string token = string.Empty; string ticket = string.Empty; if (!CacheHelper.TryGetCache<string>("access_token", out token)) { token = new HP.CPS.BLL.WeiXin.WXServices().Getaccesstoken(WxConfig.AppID, WxConfig.AppSecret); if (!string.IsNullOrEmpty(token)) { CacheHelper.SetCache("access_token", token, new TimeSpan(2, 0, 0)); } } WxConfig.Accesstoken = token; if (!CacheHelper.TryGetCache<string>("jsapi_ticket", out ticket)) { ticket = new HP.CPS.BLL.WeiXin.WXServices().Getjsapiticket(token); if (!string.IsNullOrEmpty(ticket)) { CacheHelper.SetCache("jsapi_ticket", ticket, new TimeSpan(2, 0, 0)); } } WxConfig.Jsapiticket = ticket; WxConfig.Signature = SHA1Util.getSha1(string.Format("jsapi_ticket={0}&noncestr={1}timestamp={2}&url={3}", ticket, WxConfig.NonceStr, WxConfig.Timestamp, Server.UrlEncode(Request.Url.ToString()))); } public void InitPackage() { if (int.TryParse(Convert.ToString(Request["id"]), out depId)) { Deposit = Factory.CreateFactory.CreateFundMgtBLL().Get_tb_DepositEntity(depId); sp_billno = Deposit.nv_donateCertificate; } else { Deposit = new tb_Deposit(); } int money = 0; money = Decimal.ToInt32(Deposit.m_donateAmount * 100); Hashtable Package = new Hashtable(); //请求参数集合 Package.Add("appid", WxConfig.AppID);//公众账号ID Package.Add("mch_id", WxConfig.PartnerId);//商户号 Package.Add("nonce_str", WxConfig.NonceStr);//随机字符串 Package.Add("body", Deposit.nv_projectTitle);//商品描述 Package.Add("out_trade_no", Deposit.nv_donateCertificate);//商户订单号 Package.Add("total_fee", money.ToString());//总金额 Package.Add("spbill_create_ip", Page.Request.UserHostAddress);//终端IP Package.Add("notify_url", WxConfig.NotifyUrl);//通知地址 Package.Add("trade_type", "JSAPI");//交易类型 Package.Add("openid", WxConfig.OpenId);//用户标识 WxConfig.PaySign = GetSin(Package, WxConfig.ApiToken); Package.Add("sign", WxConfig.PaySign);//签名 string pak = getXml(Package); string urlFormat = "https://api.mch.weixin.qq.com/pay/unifiedorder"; var result = PostDataToUrl.Post(urlFormat, pak); //接收微信返回的xml数据 var res = XDocument.Parse(result); if (res.Element("xml").Element("return_code").Value == "SUCCESS") { //下单成功返回 string repayId = res.Element("xml").Element("prepay_id").Value; WxConfig.Package = string.Format("prepay_id={0}", repayId); Flag = "1"; } } string GetSin(Hashtable ParametersTosin, string appkey) { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(ParametersTosin.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)ParametersTosin[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { sb.Append(k + "=" + v + "&"); } } sb.Append("key=" + appkey); return MD5Util.GetMD5(sb.ToString(), Request.ContentEncoding.BodyName).ToUpper(); } string getXml(Hashtable kvs) { string xml = ""; foreach (DictionaryEntry kv in kvs) { if (kv.Value != null) { xml += string.Format("<{0}>{1}{0}>", kv.Key, kv.Value); } } xml += ""; return xml; } }
这是接收通知页面的代码逻辑,必须要把对通知处理的结果返回给微信。如果微信发送通知后收不到回复,会以每隔30分钟的频率,向通知页面发送8次通知。
protected void Page_Load(object sender, EventArgs e)
{ string postStr = ""; ////// 微信支付回调 /// /// if (Request.HttpMethod.ToLower() == "post") { Stream s = System.Web.HttpContext.Current.Request.InputStream; byte[] b = new byte[s.Length]; s.Read(b, 0, (int)s.Length); postStr = Encoding.UTF8.GetString(b); if (!string.IsNullOrEmpty(postStr)) { var res = XDocument.Parse(postStr); if (res.Element("xml").Element("return_code").Value == "SUCCESS") { Response.Write(string.Format(@" ")); Response.End(); } Response.Write(string.Format(@" ", "FAIL", res.Element("xml").Element("return_msg").Value)); } } }
一定要注意微信配置项,和微信支付2.0不同的地方是要加一个api_token,这个参数从“微信支付商户平台”中配置,首先登陆商户平台,依次打开“账户设置”、“安全设置”、“API安全”,在API密钥中点击“设置密钥”按钮,自定义API密钥。
////// 微信配置类 /// public class WxConfig { /// /// 应用ID /// public string AppID { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXAppID"]; } } /// /// 应用密钥 /// public string AppSecret { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXAppSecret"]; } } /// /// API密钥(支付密钥) /// public string ApiToken { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXApiToken"]; } } /// /// 商户号 /// public string PartnerId { get { return (string)System.Configuration.ConfigurationManager.AppSettings["PartnerId"]; } } /// /// 接受通知的页面 /// public string NotifyUrl { get { return Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["NotifyUrl"]); } } /// /// 支付后跳转的页面 /// public string ReturnUrl { get { return Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ReturnUrl"]); } } /// /// 用户唯一标识 /// public string OpenId { get; set; } /// /// 公众号的全局唯一票据 /// public string Accesstoken { get; set; } /// /// JS-SDK临时票据 /// public string Jsapiticket { get; set; } /// /// 时间戳 /// public string Timestamp { get; set; } /// /// 随机串 /// public string NonceStr { get; set; } /// /// JS-SDK权限验证的签名 /// public string Signature { get; set; } /// /// 支付包参数 /// public string Package { get; set; } /// /// 签名方式(新版微信支付为MD5) /// public string SignType { get; set; } /// /// 支付签名 /// public string PaySign { get; set; } }