C# 微信支付前台到支付通知

<!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 = "<xml>";
        foreach (DictionaryEntry kv in kvs)
        {
            if (kv.Value != null)
            {
                xml += string.Format("<{0}>{1}</{0}>", kv.Key, kv.Value);
            }
        }
        xml += "</xml>";
        return xml;
    }
}

这是接收通知页面的代码逻辑,必须要把对通知处理的结果返回给微信。如果微信发送通知后收不到回复,会以每隔30分钟的频率,向通知页面发送8次通知。

protected void Page_Load(object sender, EventArgs e)

{
    string postStr = "";
    /// <summary>  
    /// 微信支付回调   
    /// </summary>  
    /// <param name="xml"></param>  
    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(@"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>"));
                Response.End();
            }
            Response.Write(string.Format(@"<xml><return_code><![CDATA[{0}]]></return_code><return_msg><![CDATA[{1}]]></return_msg></xml>", "FAIL", res.Element("xml").Element("return_msg").Value));
        }
    }
}

一定要注意微信配置项,和微信支付2.0不同的地方是要加一个api_token,这个参数从“微信支付商户平台”中配置,首先登陆商户平台,依次打开“账户设置”、“安全设置”、“API安全”,在API密钥中点击“设置密钥”按钮,自定义API密钥。

/// <summary>
/// 微信配置类
/// </summary>
public class WxConfig
{
    /// <summary>
    /// 应用ID
    /// </summary>
    public string AppID { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXAppID"]; } }

    /// <summary>
    /// 应用密钥
    /// </summary>
    public string AppSecret { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXAppSecret"]; } }

    /// <summary>
    /// API密钥(支付密钥)
    /// </summary>
    public string ApiToken { get { return (string)System.Configuration.ConfigurationManager.AppSettings["WXApiToken"]; } }

    /// <summary>
    /// 商户号
    /// </summary>
    public string PartnerId { get { return (string)System.Configuration.ConfigurationManager.AppSettings["PartnerId"]; } }

    /// <summary>
    /// 接受通知的页面
    /// </summary>
    public string NotifyUrl { get { return Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["NotifyUrl"]); } }

    /// <summary>
    /// 支付后跳转的页面
    /// </summary>
    public string ReturnUrl { get { return Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["ReturnUrl"]); } }

    /// <summary>
    /// 用户唯一标识
    /// </summary>
    public string OpenId { get; set; }

    /// <summary>
    /// 公众号的全局唯一票据
    /// </summary>
    public string Accesstoken { get; set; }

    /// <summary>
    /// JS-SDK临时票据
    /// </summary>
    public string Jsapiticket { get; set; }

    /// <summary>
    /// 时间戳
    /// </summary>
    public string Timestamp { get; set; }

    /// <summary>
    /// 随机串
    /// </summary>
    public string NonceStr { get; set; }

    /// <summary>
    /// JS-SDK权限验证的签名
    /// </summary>
    public string Signature { get; set; }

    /// <summary>
    /// 支付包参数
    /// </summary>
    public string Package { get; set; }

    /// <summary>
    /// 签名方式(新版微信支付为MD5)
    /// </summary>
    public string SignType { get; set; }

    /// <summary>
    /// 支付签名
    /// </summary>
    public string PaySign { get; set; }
}

猜你喜欢

转载自blog.csdn.net/yelin042/article/details/80770229