简介

Senparc.Weixin SDK 是由盛派网络(Senparc)团队自主研发的针对微信各模块的 开发套(C#SDK),
已全面支持微信公众号、微信支付、企业号、开放平台、JSSDK、摇一摇周边等模块。 快使用 Senparc.Weixin SDK 轻松打造微信各平台的扩展应用吧!

开发步骤

模式介绍

模式一
商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号)。用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商户后台系统(需要设置支付回调URL),商户后台系统根据productid生成支付交易,最后微信支付系统发起用户支付流程。

商户支付回调URL设置指引:进入公众平台–>微信支付–>开发配置–>扫码支付–>修改

微信支付java 开发 微信支付系统开发_css

模式二
户后台系统调用微信支付【统一下单API】生成预付交易,将接口返回的链接生成二维码,用户扫码后输入密码完成支付交易。注意:该模式的预付单有效期为2小时,过期后无法支付。
业务流程说明:
    (1)商户后台系统根据用户选购的商品生成订单。
    (2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;
    (3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。
    (4)商户后台系统根据返回的code_url生成二维码。
    (5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。
    (6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。
    (7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。
    (8)微信支付系统根据用户授权完成支付交易。
    (9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
    (10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
    (11)未收到支付通知的情况,商户后台系统调用【查询订单API】。
    (12)商户确认订单已支付后给用户发货。

生成二维码规则
        对应链接格式:weixin://wxpay/bizpayurl?sr=XXXXX。请商户调用第三方库将code_url生成二维码图片。该模式链接较短,生成的二维码打印到结账小票上的识别率较高。

代码实现(使用模式二)

前端代码

<div class="ZhiFu_All">
        <div class="ZhiFu_Money">请填入预付金额:<input type="number" id="money" name="money" />元<span>当前余额:@ViewBag.Money元</span><span id="error"></span></div>
        <div class="ZhiFu_Fangshi">请选择支付方式:</div>
        <ul class="ZhiFu_UL">
            <li>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" checked="checked" type="radio" />
                        <img src="/Content/state/img/WePayLogo.png" />
                        <img class="TUIjian" src="/Content/state/img/tuijian.png" />
                    </label>
                </div>
            </li>
            <li>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank1.png" />
                    </label>
                </div>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank2.png" />
                    </label>
                </div>
            </li>
            <li>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank3.png" />
                    </label>
                </div>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank4.png" />
                    </label>
                </div>
            </li>
            <li>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank5.png" />
                    </label>
                </div>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank6.png" />
                    </label>
                </div>
            </li>
            <li>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank7.png" />
                    </label>
                </div>
                <div class="Div_css">
                    <label>
                        <input name="WXbank" type="radio" />
                        <img src="/Content/state/img/bank8.png" />
                    </label>
                </div>
            </li>
        </ul>
        <div class="ZhiFu_sum">
            <input type="submit" id="WX_zhifu" value="继续下一步" />
        </div>
    </div>
    //保存生成的订单
<input type="hidden" value="0" id="OrderNo" />

<!-- 隐藏层  当用户点击继续下一步(相当于充值)时显示此层-->
<div id="WX_All" class="WX_zhifu">
    <div class="WX_left">
        <div class="WX_title">
            <img src="/Content/state/img/tuijian.png" />
            <span>使用微信支付</span>
            <label class="WX_Close">x</label>
        </div>
        <div class="WX_All">
            <div class="WX_imgLogo">
                <img src="/Content/state/img/WePayLogo.png" />
            </div>
            <div>
                <div class="WX_jinE">
                    <ul>
                        <li id="OrderNum">订单编号:</li>

                    </ul>
                </div>
                <span class="WX_Money">应付金额:<label class="WX_Moneys" id="trueMoney">33</label></span>
            </div>
            <div class="WX_ewma">
                <div class="WX_ewmaL">
                    <img src="/Content/state/img/gongzhonghao.jpg" id="code_url" />
                    <img src="/Content/state/img/shuoming.png" />
                </div>
                <div class="WX_shifan">
                    <img src="/Content/state/img/shouj.png" />
                </div>
                <div class="clear"></div>
            </div>
        </div>
    </div>
</div>
    <script type="text/javascript" language="javascript">

          //用来循环检测订单是否支付完成  然后页面进行跳转 
            $(document).ready(function () {
                setInterval("ajaxstatus()", 3000);
            });

            function ajaxstatus() {
                //如果OrderNo不等于0时 说明用户已经生成订单 就开始轮询检查用户支付成功没 
                //微信的回调
                if ($("#OrderNo").val() != "0") {
                    $.ajax({
                        url: "/Member/MemWeixinPay/Search",
                        type: "post",
                        dataType: "text",
                        data: { OutID: $("#OrderNo").val() },
                        success: function (data) {
                            //                  alert(data);
                            if (data == "1") { //订单状态为1表示支付成功
                                window.location.href = "/Member/MemAccount/Index"; //页面跳转
                            }
                        },
                        error: function () {
                            console.log("请求订单状态出错");
                        }
                    });
                }
            }
            $("#WX_zhifu").click(function () {
                var r = /^\+?[1-9][0-9]*$/;  //正整数  
                var Money = $("#money").val();
                var flag = r.test(Money);
                if (flag == false) {
                    $("#error").html("请输入整数");
                    return false;
                }
                //支付金额
                $("#trueMoney").html("" + Money);
                //获取订单编号 
                var num = generateMixed(15);
                $("#OrderNum").html("订单编号:" + num);
                //订单编号保存到隐藏域名里面
                $("#OrderNo").val(num);
                //获取返回的二维码
                $("#code_url").attr("src", "/Member/MemWeixinPay/WeixinPayErweima?price=" + Money + "&outTradeNo=" + num + "");
                //显示出二维码支付的一个层  层里面放一个微信返回的支付二维码和订单编号  订单金额
                $("#WX_All").show();

            });
            $(".WX_Close").click(function () {
                $("#WX_All").hide();
            });             
            //生成订单编号 
            function generateMixed(n) {
                var chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
                var res = "";
                for(var i = 0; i < n ; i ++) {
                    var id = parseInt(10 * Math.random());

                    res += chars[id]+"";
                }
                return res;
            }
</script>

后端代码

private static TenPayV3Info _tenPayV3Info;



        public static TenPayV3Info TenPayV3Info
        {
            get
            {
                if (_tenPayV3Info == null)
                {
                    _tenPayV3Info = new TenPayV3Info("appid", "AppSecret", "商户ID", "密码", "回调接口");
                    TenPayV3InfoCollection.Register(_tenPayV3Info);
                }
                return _tenPayV3Info;
            }
        }

        /// <summary>
        /// 返回二维码
        /// </summary>
        /// <returns></returns>
        public string WeixinPayErweima(int price,string outTradeNo)
        {
            UserBasic user = userBasicBll.GetUser(LoginUserID);
            if (user == null)
            {
                return "";
            }
            var body = "充值";
            var timeStamp = TenPayV3Util.GetTimestamp();
            var nonceStr = TenPayV3Util.GetNoncestr();
            //这个商户订单号可以通过前端传入  也可以通过后台生成。  现在我们是前端传入的
            string sp_billno = outTradeNo;
            if (string.IsNullOrEmpty(sp_billno))
            {
                //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
                sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId/*10位*/, DateTime.Now.ToString("yyyyMMddHHmmss"),
                    TenPayV3Util.BuildRandomStr(6));
            }

           // 添加一个交易记录  放在本地服务器里面
            //等会儿前端轮询就好判断用户订单是否支付成功
            TenPayV3UnifiedorderRequestData od = new TenPayV3UnifiedorderRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, price*100, Request.UserHostAddress, TenPayV3Info.TenPayV3Notify, TenPayV3Type.NATIVE, "", TenPayV3Info.Key, nonceStr);
            var order = TenPayV3.Unifiedorder(od);
            var erweima = order.code_url;
            String data = erweima;
            //生成二维码
            QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
            qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
            qrCodeEncoder.QRCodeScale = 4;
            qrCodeEncoder.QRCodeVersion = 8;
            qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
            System.Drawing.Bitmap image = qrCodeEncoder.Encode(data);
            System.IO.MemoryStream MStream = new System.IO.MemoryStream();
            image.Save(MStream, System.Drawing.Imaging.ImageFormat.Png);
            Response.ClearContent();
            Response.ContentType = "image/Png";
            Response.BinaryWrite(MStream.ToArray());
            return "";
        }
//支付成功回调接口
  public string Success()
  {

            //获取微信返回的数据
            string resultFromWx = getPostStr();  
            //转换成xml文档       
            var ress = XDocument.Parse(resultFromWx);
            //返回给微信接口 提示微信处理成功
            string data = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            //通信成功
            if (ress.Element("xml").Element("return_code").Value == "SUCCESS")
            {
                if (ress.Element("xml").Element("result_code").Value == "SUCCESS")
                {
                    //商户订单号<><!
                    string outNos = ress.Element("xml").Element("out_trade_no").Value;
                    //微信订单号
                    string tranId = ress.Element("xml").Element("transaction_id").Value; 

                    if (outNos == "")
                    {

                        return data;
                    }
                     //这里可以不用再次查询了  但是我还是查询了一个次 为了更好的验证
                    string norcestr = TenPayV3Util.GetNoncestr();
                    var xmlDataInfo = new TenPayV3OrderQueryRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, tranId, norcestr, outNos, TenPayV3Info.Key);
                    var result = TenPayV3.OrderQuery(xmlDataInfo);
                    if (result == null)
                    {
                        return data;
                    }
                    if (result.trade_state != "SUCCESS")
                    {
                        return data;
                    }
                    //微信端返回充值成功  跟据商户订单号获取交易记录  修改交易状态
                    //充值完成

                }
                else
                {

                }
            }
            return data;
        }

        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);
        }